Frage
Jetzt, wo es ist klar, was ein metaclass ist, gibt es ein zugehöriges Konzept, dass ich die ganze Zeit, ohne zu wissen, was es wirklich bedeutet.
Ich nehme an jedem einmal einen Fehler mit Klammer gemacht, in einem resultierenden „Objekt ist nicht aufrufbar“ Ausnahme. Was mehr ist, mit __init__
und __new__
führen zu fragen, was dieser blutigen __call__
kann verwendet werden.
Könnten Sie einige Erklärungen geben Sie mir, auch Beispiele mit der magischen Methode?
Lösung
Ein aufrufbar ist alles, was genannt werden kann.
Die built-in aufrufbar (PyCallable_Check in objects.c) überprüft, ob das Argument entweder:
- eine Instanz einer Klasse mit einem __ call __ Methode oder
- ist von einem Typ, der einen nicht null tp_call (C struct) Element, die Kündbarkeit ansonsten angibt (wie in Funktionen, Methoden etc.)
Die Methode mit dem Namen __ call __ ist ( nach in der Dokumentation )
Wird aufgerufen, wenn die Instanz ‚‘ genannt ‚‘ als Funktion
Beispiel
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
Andere Tipps
Von Python Quellen 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;
}
}
Dort heißt es:
- Wenn ein Objekt eine Instanz einer Klasse dann aufrufbar ist iff es hat
__call__
Attribut. - Else das Objekt
x
ist aufrufbar iffx->ob_type->tp_call != NULL
Desciption von tp_call
Feld :
ternaryfunc tp_call
Eine optionale Zeiger auf eine Funktion, die Arbeitsgeräte Aufruf des Objekts. Das sollte sein NULL, wenn das Objekt nicht aufrufbar ist. Die Signatur ist die gleiche wie für PyObject_Call (). Dieses Feld ist geerbt von Subtypen.
Sie können immer eingebaute in callable
Funktion verwenden, um festzustellen, ob bestimmte Objekt aufrufbar ist oder nicht; oder besser noch gerade nennen es und fangen TypeError
später. callable
entfernt in Python 3.0 und 3.1, die Verwendung callable = lambda o: hasattr(o, '__call__')
oder isinstance(o, collections.Callable)
.
Beispiel, eine vereinfachte Cache-Implementierung:
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
Verbrauch:
@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
Beispiel von Standard-Bibliothek, Datei site.py
, Definition Einbau-exit()
und quit()
Funktionen:
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')
Ein aufrufbar ist ein Objekt können Sie runde Klammern () und schließlich passieren einige Parameter verwenden, ebenso wie Funktionen.
Jedes Mal, wenn Sie eine Funktion Python definieren erstellt ein aufrufbare Objekt.
: Im Beispiel können Sie die Funktion func auf diese Weise (es ist das gleiche) definierenclass a(object):
def __call__(self, *args):
print 'Hello'
func = a()
# or ...
def func(*args):
print 'Hello'
Sie könnten diese Methode anstelle von Methoden wie doit oder run , ich denke, es ist nur mehr klar zu sehen, obj () als obj.doit ()
Lassen Sie mich erklären rückwärts:
das Betrachten ...
foo()
... als syntaktischer Zucker für:
foo.__call__()
Wo foo
kann ein beliebiges Objekt sein, das auf __call__
reagiert. Wenn ich jedes Objekt sage, meine ich es: eingebaute Typen, Ihre eigenen Klassen und die Instanzen
Im Fall von eingebauten Typen, wenn Sie schreiben:
int('10')
unicode(10)
Sie sind im Wesentlichen zu tun:
int.__call__('10')
unicode.__call__(10)
Das ist auch, warum Sie nicht foo = new int
in Python: Sie gerade das Klassenobjekt macht eine Instanz davon auf __call__
zurückzukehren. Die Art und Weise Python diese löst, ist sehr elegant in meiner Meinung nach.
eine aufrufbare ist ein Objekt, das die __call__
Methode hat. Das heißt, Sie können gefälschte aufrufbaren Funktionen oder tun nette Dinge wie wo Sie nehmen eine Funktion und fügen Sie etwas, das sie oder füllt einige der Parameter verbessert, etwas Rückkehr, die wiederum (bekannt als Currying in der funktionalen Programmierung Kreise).
Einige Schreibfehler werden die Dolmetscher haben versucht, etwas rufen Sie nicht, wie (zum Beispiel) ein String beabsichtigen. Dies kann zu Fehlern in dem der Interpreter versucht, eine nicht-kündbare Anwendung auszuführen. Sie können dies geschieht in einem Python-Interpreter sehen von unten etwas wie das Transkript zu tun.
[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
>>>
Ganz einfach, ein „aufrufbar“ ist etwas, das wie eine Methode aufgerufen werden kann. Die eingebaute Funktion „aufrufbar ()“ wird Ihnen sagen, ob etwas erscheint aufrufbar zu sein, ebenso wie für eine Anruf Überprüfung Eigenschaft. Funktionen aufrufbar sind, wie es Klassen, Klasseninstanzen können aufrufbar sein. Sehen Sie mehr über dieses hier und hier .
__call__
macht jedes Objekt als Funktion aufrufbar sein.
Dieses Beispiel erzeugt folgende Ausgabe 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 eine aufrufbare ist ein Gegenstand, die Art, die eine __call__
Methode hat:
>>> 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
So einfach wie das:)
Dies kann natürlich überlastet werden:
>>> class Foo(object):
... def __call__(self):
... return 42
...
>>> f = Foo()
>>> f()
42
Es ist etwas, können Sie „(args)“ nach und erwarten, setzen sie zu arbeiten. Ein aufrufbar ist in der Regel ein Verfahren oder eine Klasse. Methoden erhalten genannt, Klassen instanziiert erhalten.
Um zu überprüfen, Funktion oder Methode der Klasse aufrufbar ist oder nicht, dass bedeutet, dass wir diese Funktion aufrufen können.
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
Callables implementieren die __call__
spezielle Methode, um jedes Objekt mit einem solchen Verfahren ist aufrufbar.
aufrufbare ist eine Art oder eine Klasse von „build-in-Funktion oder Method“ mit einem Verfahren Anruf
>>> type(callable)
<class 'builtin_function_or_method'>
>>>
Beispiel: Drucken ist eine aufrufbare Objekt. Mit einer Build-in-Funktion __ call __ Wenn Sie die Drucken aufrufen Funktion erzeugt Python ein Objekt vom Typ Druck aus und ruft seine Methode __ call __ Führen der Parameter, falls vorhanden.
>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>
Danke. Grüße, Maris