2010-11-28 5 views
4

Wenn dies ausgeführt wird ...Wenn eine in der Klasse eingebettete Funktion die "Methode" der Klasse ist?

class A: 
    def b(self, a): 
     print a 
    print dir(b) 
print dir(A.b) 

Es gibt das Ergebnis:

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 
'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'] 

['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__', 
'__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', 
'__repr__', '__setattr__', '__str__', 'im_class', 'im_func', 'im_self'] 

warum dies unterscheidet?

+0

Interessant - ich dachte, ich wüsste die Antwort, aber sobald ich versuchte, es zu erklären ... – Steve314

+0

Kurze Antwort: Das 'print dir (b) 'bezieht sich auf ein Funktionsobjekt und was angezeigt wird, ist effektiv' dir (types.FunctionTyp e) ', während sie im 'print dir (A.b)' auf einem (ungebundenen) Instanzverfahren läuft, das ** durch das Klassenobjekt 'A' ** abgerufen wurde. – martineau

Antwort

7

In Python 2, der zweite Fall gibt eine ungebundene Methode zurück, und der erste Fall eine Funktion. Von the documentation, Hervorhebung von mir:

Benutzerdefinierte Methode Objekte erstellt werden kann, wenn ein Attribut einer Klasse bekommen (vielleicht über eine Instanz dieser Klasse), wenn das Attribut eine benutzerdefinierte Funktion Objekt ist, ein ungebundenes benutzerdefiniertes Methodenobjekt oder ein Klassenmethodenobjekt. Wenn das Attribut ein benutzerdefiniertes Methodenobjekt ist, wird ein neues Methodenobjekt nur erstellt, wenn die Klasse, von der es abgerufen wird, die gleiche oder eine abgeleitete Klasse der im ursprünglichen Methodenobjekt gespeicherten Klasse ist. Andernfalls wird das ursprüngliche Methodenobjekt wie es ist verwendet.

So erhalten Sie eine Methode rein wegen des A. Präfix. Die ursprüngliche Funktion ist weiterhin über das Attribut im_func (oder ab 2.6 auch __func__) der Methode zugänglich. Beachten Sie auch, dass Sie bei jedem Zugriff ein neues Methodenobjekt erhalten, so dass A.b is A.bFalse zurückgibt!

In Python 3, nicht ungebundenen Methoden nicht als separate Art existieren nicht mehr, und Sie erhalten die gleiche Leistung von beiden Druck Anrufe erhalten:

$ python3 
Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33) 
[GCC 4.4.5] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> class A: 
...  def b(self, a): 
...   print(a) 
...  print(dir(b)) 
... 
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 
>>> print(dir(A.b)) 
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 

Wenn Sie dir von id Sie sehen ersetzen dass es das gleiche Funktionsobjekt in beiden Fällen ist, in Python 3.

Verwandte Themen