Domanda

Ora che è chiaro che cos'è una metaclasse , è associato un concetto che uso sempre senza sapere cosa significhi davvero.

Suppongo che tutti abbiano commesso una volta un errore tra parentesi, risultando in un "oggetto non richiamabile". eccezione. Inoltre, l'uso di __init__ e __new__ porta a chiedersi per cosa possa essere usato questo sanguinoso __call__ .

Potresti darmi qualche spiegazione, inclusi esempi con il metodo magico?

È stato utile?

Soluzione

Un callable è tutto ciò che può essere chiamato.

Il richiamabile incorporato (PyCallable_Check in objects.c) verifica se l'argomento è:

  • un'istanza di una classe con un metodo __call__ o
  • è di un tipo che ha un membro tp_call (c struct) non nullo che indica diversamente la richiamabilità (come in funzioni, metodi ecc.)

Il metodo denominato __call__ è ( secondo alla documentazione )

  

Chiamato quando l'istanza è "chiamata" come funzione

Esempio

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

foo_instance = Foo()
foo_instance() #this is calling the __call__ method

Altri suggerimenti

Dalle fonti di 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;
    }
}

Dice:

  1. Se un oggetto è un'istanza di una classe, allora è richiamabile iff ha l'attributo __call__ .
  2. Altrimenti l'oggetto x è richiamabile iff x- > ob_type- > tp_call! = NULL

Descrizione del tp_call field :

  

ternaryfunc tp_call Un facoltativo   puntatore a una funzione che implementa   chiamando l'oggetto. Questo dovrebbe essere   NULL se l'oggetto non è richiamabile.   La firma è la stessa di   PyObject_Call (). Questo campo è   ereditato da sottotipi.

Puoi sempre usare la funzione callable integrata per determinare se un dato oggetto è richiamabile o meno; o meglio, basta chiamarlo e catturare TypeError in un secondo momento. callable viene rimosso in Python 3.0 e 3.1, utilizzare callable = lambda o: hasattr (o, '__call__') o isinstance (o, collections.Callable) .

Esempio, un'implementazione della cache semplicistica:

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    

Utilizzo:

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

Esempio dalla libreria standard, file site.py , definizione delle funzioni integrate exit () e quit () :

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')

Un callable è un oggetto che consente di utilizzare la parentesi tonda () e alla fine passare alcuni parametri, proprio come le funzioni.

Ogni volta che si definisce una funzione python crea un oggetto richiamabile. Ad esempio, puoi definire la funzione func in questi modi (è la stessa):

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

func = a()

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

Potresti usare questo metodo invece di metodi come doit o esegui , penso che sia solo più chiaro vedere obj () che obj.doit ()

Lasciami spiegare al contrario:

Considera questo ...

foo()

... come zucchero sintattico per:

foo.__call__()

Dove foo può essere qualsiasi oggetto che risponda a __call__ . Quando dico qualsiasi oggetto, intendo: tipi integrati, le tue classi e le loro istanze.

Nel caso di tipi predefiniti, quando scrivi:

int('10')
unicode(10)

Stai essenzialmente facendo:

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

Questo è anche il motivo per cui non hai foo = new int in Python: fai semplicemente restituire all'oggetto classe un'istanza su __call__ . Il modo in cui Python risolve questo è molto elegante secondo me.

Un callable è un oggetto che ha il metodo __call__ . Ciò significa che puoi fingere funzioni richiamabili o fare cose ordinate come Applicazione con funzioni parziali dove prendi una funzione e aggiungi qualcosa che la migliora o riempie alcuni parametri, restituendo qualcosa che può essere chiamato a sua volta (noto come Currying nei circoli di programmazione funzionale).

Alcuni errori tipografici avranno l'interprete che tenta di chiamare qualcosa che non intendevi, come (ad esempio) una stringa. Ciò può generare errori nei casi in cui l'interprete tenta di eseguire un'applicazione non richiamabile. Puoi vederlo accadere in un interprete Python facendo qualcosa di simile alla trascrizione di seguito.

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

Molto semplicemente, un "callable" è qualcosa che può essere chiamato come un metodo. La funzione integrata "callable ()" ti dirà se qualcosa sembra essere richiamabile, così come la ricerca di una proprietà chiamata . Le funzioni sono richiamabili come le classi, le istanze di classe possono essere richiamabili. Scopri di più su questo qui e qui .

__call__ rende qualsiasi oggetto richiamabile come funzione.

Questo esempio genererà 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)

In Python un callable è un oggetto il cui tipo ha un metodo __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

Semplice come quello :)

Questo ovviamente può essere sovraccarico:

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

È qualcosa che puoi mettere " (args) " dopo e aspettiamo che funzioni. Un callable è di solito un metodo o una classe. Vengono chiamati i metodi, le classi vengono istanziate.

Controllare che la funzione o il metodo della classe sia richiamabile o meno significa che possiamo chiamare quella funzione.

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

i callable implementano il metodo speciale __call__ in modo che qualsiasi oggetto con tale metodo sia richiamabile.

Callable è un tipo o una classe di " Funzione incorporata o Metodo " con un metodo Chiama

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

Esempio: stampa è un oggetto richiamabile. Con una funzione integrata __call__ Quando invochi la funzione stampa , Python crea un oggetto di tipo stampa e invoca il suo metodo __call__ passando eventuali parametri.

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

Grazie. Saluti, Maris

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top