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?

War es hilfreich?

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:

  1. Wenn ein Objekt eine Instanz einer Klasse dann aufrufbar ist iff es hat __call__ Attribut.
  2. Else das Objekt x ist aufrufbar iff x->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) definieren
class 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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top