web-dev-qa-db-fra.com

Qu'est-ce qu'un "callable"?

Maintenant que c'est clair c'est quoi une métaclasse , il y a un concept associé que j'utilise tout le temps sans savoir ce que ça veut vraiment dire.

Je suppose que tout le monde a commis une fois une erreur avec une parenthèse, ce qui a entraîné une exception "l'objet n'est pas appelable". De plus, utiliser __init__ et __new__ conduit à se demander à quoi sert ce sanglant __call__.

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

279
e-satis

Un appelable est tout ce qui peut être appelé.

Le intégré appelable (PyCallable_Check dans objects.c) vérifie si l'argument est l'un des suivants:

  • une instance d'une classe avec une méthode __call__ ou
  • est d'un type qui a un membre non nul tp_call (c struct) qui indique une callabilité autre (comme dans les fonctions, les méthodes, etc.)

La méthode nommée __call__ est ( selon la documentation )

Appelé lorsque l'instance est "" appelée "en tant que fonction

Exemple

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

foo_instance = Foo()
foo_instance() #this is calling the __call__ method
280
Florian Bösch

Depuis les sources de Python object.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;
    }
}
_

Ça dit:

  1. Si un objet est une instance d'une classe, il est appelable si et seulement si il possède l'attribut ___call___.
  2. Sinon l'objet x est appelable si et seulement si _x->ob_type->tp_call != NULL_

Description de champ _tp_call_ :

_ternaryfunc tp_call_ Un pointeur facultatif sur une fonction qui implémente l'appel de l'objet. Cela devrait être NULL si l'objet n'est pas appelable. La signature est la même que pour PyObject_Call (). Ce champ est hérité par 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, appelez-le et attrapez TypeError plus tard. callable est supprimé dans Python 3.0 et 3.1, utilisez callable = lambda o: hasattr(o, '__call__') ou isinstance(o, collections.Callable).

Exemple, une implémentation simpliste du cache:

_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    
_

Usage:

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

Exemple tiré de la 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')
_
77
jfs

Un callable est un objet qui vous permet d'utiliser des parenthèses arrondies () et éventuellement de transmettre certains paramètres, tout comme les fonctions.

Chaque fois que vous définissez une fonction, python crée un objet appelable. Par exemple, vous pourriez définir la fonction func de cette manière (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 à la place de méthodes telles que doit ou run, je pense que c'est plus clair de voir obj () qu'obj.doit ()

36
Andrea Ambu

Permettez-moi d'expliquer à l'envers:

Considère ceci...

foo()

... en sucre syntaxique pour:

foo.__call__()

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

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

int('10')
unicode(10)

Vous faites essentiellement:

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

C'est aussi pourquoi vous n'avez pas foo = new int en Python: vous faites simplement en sorte que l'objet de classe retourne une instance de celui-ci sur __call__. La façon dont Python résout ce problème est très élégante à mon avis.

31
hcalves

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

Certaines erreurs typographiques peuvent amener l’interprète à appeler quelque chose que vous n’avez pas voulu, tel que (par exemple) une chaîne. 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ète python en effectuant 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

Tout simplement, un "appelable" est quelque chose qui peut être appelé comme une méthode. La fonction intégrée "callable ()" vous dira si quelque chose semble être appelable, tout comme la recherche d'une propriété call . Les fonctions sont appelables comme les classes, les instances de classe peuvent être appelées. Voir plus à ce sujet ici et ici .

7
Joe Skora

__call__ permet à tout objet d'être appelable en tant que fonction.

Cet exemple affichera 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
MvdD

Dans Python, un appelable 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 :)

Ceci peut bien sûr être surchargé:

>>> class Foo(object):
...  def __call__(self):
...   return 42
... 
>>> f = Foo()
>>> f()
42
5
Armin Ronacher

Vérifier que la fonction ou la méthode de la 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
Ravi Singh

C'est quelque chose que vous pouvez mettre "(args)" après et vous attendre à ce que cela fonctionne. Un callable est généralement une méthode ou une classe. Les méthodes sont appelées, les classes sont instanciées.

2
Kevin Conner

callables implémente la méthode spéciale __call__ afin qu'un objet doté d'une telle méthode puisse être appelé.

1
cobie

Callable est un type ou une classe de "Fonction ou méthode intégrée" avec une méthode call

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

Exemple: print est un objet appelable. Avec une fonction intégrée _ CALL _ Lorsque vous appelez la fonction print, Python crée un objet de type print et l'invoque sa méthode _ CALL _ en passant les paramètres éventuels.

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

Je vous remercie. Cordialement, Maris

0
maris