Qu'est-ce qu'un" appelable " en Python?

maintenant qu'il est clair ce qu'est une métaclasse , il y a un concept associé que j'utilise tout le temps sans savoir ce qu'il signifie vraiment.

je suppose que tout le monde a fait une erreur avec une parenthèse, résultant en une exception" objet n'est pas appelable". De plus, l'utilisation de __init__ et __new__ conduit à se demander à quoi ce sanglant __call__ peut être utilisé.

Pourriez-vous me donner quelques explications, y compris des exemples avec la méthode magique ?

245
demandé sur Community 2008-09-21 19:34:32

12 réponses

un appelant est tout ce qui peut être appelé.

Le built-in callable (PyCallable_Check dans les objets.c) vérifie si l'argument est:

  • une instance d'une classe avec un __appel__ méthode
  • est d'un type qui a un non null tp_call (struct c) le membre qui indique callability autrement (par exemple comme dans les fonctions, les méthodes, etc.)

La méthode nommée __appel__ ( , selon la documentation )

appelé lorsque l'instance est "appelé" comme une fonction

exemple

class Foo:
  def __call__(self):
    print 'called'

foo_instance = Foo()
foo_instance() #this is calling the __call__ method
252
répondu Florian Bösch 2013-03-22 10:03:19

De Python sources objet.c :

/* Test whether an object can be called */

int
PyCallable_Check(PyObject *x)
{
    if (x == NULL)
        return 0;
    if (PyInstance_Check(x)) {
        PyObject *call = PyObject_GetAttrString(x, "__call__");
        if (call == NULL) {
            PyErr_Clear();
            return 0;
        }
        /* Could test recursively but don't, for fear of endless
           recursion if some joker sets self.__call__ = self */
        Py_DECREF(call);
        return 1;
    }
    else {
        return x->ob_type->tp_call != NULL;
    }
}

Il dit:

  1. Si un objet est une instance d'une classe, alors il est appelable iff il a __call__ attribut.
  2. Sinon l'objet x est appelable iff x->ob_type->tp_call != NULL

Desciption de tp_call champ :

ternaryfunc tp_call facultatif pointeur vers une fonction qui implémente l'appel de l'objet. Cela devrait être La valeur NULL si l'objet n'est pas appelable. La signature est la même que pour PyObject_Call(). Ce champ est héritées par les sous-types.

vous pouvez toujours utiliser la fonction intégrée callable pour déterminer si un objet donné est appelable ou non; ou mieux encore, il suffit de l'appeler et de saisir TypeError plus tard. callable est supprimé en Python 3.0 et 3.1, utilisez callable = lambda o: hasattr(o, '__call__') ou isinstance(o, collections.Callable) .

exemple, une implémentation de cache simpliste:

class Cached:
    def __init__(self, function):
        self.function = function
        self.cache = {}

    def __call__(self, *args):
        try: return self.cache[args]
        except KeyError:
            ret = self.cache[args] = self.function(*args)
            return ret    

Utilisation:

@Cached
def ack(x, y):
    return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1) 

exemple de bibliothèque standard, fichier site.py , définition des fonctions exit() et quit() intégrées:

class Quitter(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return 'Use %s() or %s to exit' % (self.name, eof)
    def __call__(self, code=None):
        # Shells like IDLE catch the SystemExit, but listen when their
        # stdin wrapper is closed.
        try:
            sys.stdin.close()
        except:
            pass
        raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')
71
répondu jfs 2014-01-02 03:22:34

un callable est un objet qui vous permet d'utiliser la parenthèse ronde ( ) et éventuellement passer quelques paramètres, tout comme les fonctions.

Chaque fois que vous définissez une fonction python crée un objet appelable. Par exemple, vous pouvez définir la fonction func de cette façon (c'est la même chose):

class a(object):
    def __call__(self, *args):
        print 'Hello'

func = a()

# or ... 
def func(*args):
    print 'Hello'

, Vous pouvez utiliser cette méthode au lieu de méthodes comme doit ou exécuter , je je pense que c'est juste plus clair de voir obj() que obj.doit ()

31
répondu Andrea Ambu 2008-09-26 13:31:26

Laissez-moi vous expliquer en arrière:

considérez ceci...

foo()

... comme sucre syntactique pour:

foo.__call__()

foo peut être n'importe quel objet qui répond à __call__ . Quand je dis n'importe quel objet, je le pense: des types intégrés, vos propres classes et leurs instances.

Dans le cas de types intégrés, lorsque vous écrivez:

int('10')
unicode(10)

vous faites essentiellement:

int.__call__('10')
unicode.__call__(10)

C'est aussi la raison pour laquelle vous n'avez pas foo = new int en Python: vous faites simplement que l'objet de classe retourne une instance de celui-ci sur __call__ . La façon dont Python résout cela est très élégant à mon avis.

26
répondu hcalves 2013-03-22 23:38:33

un appelable est un objet qui a la méthode __call__ . Cela signifie que vous pouvez simuler des fonctions appelant ou faire des choses soignées comme application de fonction partielle où vous prenez une fonction et ajouter quelque chose qui l'améliore ou remplit certains des paramètres, retournant quelque chose qui peut être appelé à son tour (connu comme Currying dans les cercles de programmation fonctionnelle).

certaines erreurs typographiques auront le interprète essayant d'appeler quelque chose que vous n'aviez pas l'intention, comme (par exemple) une chaîne de caractères. Cela peut produire des erreurs lorsque l'interpréteur tente d'exécuter une application non appelable. Vous pouvez voir cela se produire dans un interpréteur python en faisant quelque chose comme la transcription ci-dessous.

[nigel@k9 ~]$ python
Python 2.5 (r25:51908, Nov  6 2007, 15:55:44) 
[GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'aaa'()    # <== Here we attempt to call a string.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> 
11
répondu ConcernedOfTunbridgeWells 2008-09-21 15:51:44

Tout simplement, un "callable" est quelque chose qui peut être appelé comme une méthode. La fonction intégrée "callable () "vous indiquera si quelque chose semble être callable, tout comme la vérification d'une propriété call . Les fonctions sont appelables comme le sont les classes, les instances de classe peuvent être appelables. En savoir plus sur ce ici et ici .

7
répondu Joe Skora 2008-09-21 15:43:20

__call__ rend n'importe quel objet callable comme une fonction.

cet exemple produira 8:

class Adder(object):
  def __init__(self, val):
    self.val = val

  def __call__(self, val):
    return self.val + val

func = Adder(5)
print func(3)
6
répondu MvdD 2008-09-21 15:49:28

en Python un callable est un objet dont le type a une méthode __call__ :

>>> class Foo:
...  pass
... 
>>> class Bar(object):
...  pass
... 
>>> type(Foo).__call__(Foo)
<__main__.Foo instance at 0x711440>
>>> type(Bar).__call__(Bar)
<__main__.Bar object at 0x712110>
>>> def foo(bar):
...  return bar
... 
>>> type(foo).__call__(foo, 42)
42

aussi simple que cela:)

cela bien sûr peut être surchargé:

>>> class Foo(object):
...  def __call__(self):
...   return 42
... 
>>> f = Foo()
>>> f()
42
5
répondu Armin Ronacher 2008-09-21 16:37:09

C'est quelque chose que vous pouvez mettre "(args)" après et espérer qu'il fonctionne. Un appelable est habituellement une méthode ou une classe. Les méthodes sont appelées, les classes sont instanciées.

2
répondu Kevin Conner 2008-09-21 15:43:44

pour vérifier la fonction ou la méthode de classe est appelable ou non cela signifie que nous pouvons appeler cette fonction.

Class A:
    def __init__(self,val):
        self.val = val
    def bar(self):
        print "bar"

obj = A()      
callable(obj.bar)
True
callable(obj.__init___)
False
def foo(): return "s"
callable(foo)
True
callable(foo())
False
2
répondu Ravi Singh 2016-09-20 11:12:01

Callable est un type ou une classe de "Build-in function or Method" avec une méthode appel

>>> type(callable)
<class 'builtin_function_or_method'>
>>>

exemple: imprimer est un objet appelable. Avec une fonction intégrée _ _ call _ _ _ Lorsque vous invoquez la fonction print , Python crée un objet de type print et invoque sa méthode _ _ _ call _ _ en passant les paramètres si tout.

>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>

Merci. Égard, Maris

2
répondu maris 2017-04-07 07:10:48

callables implémenter la méthode spéciale __call__ donc tout objet avec une telle méthode est callable.

1
répondu cobie 2012-05-07 21:40:12