Python-Methodensuche, statische vs. Instanz

9

Bis vor einer Stunde war ich überzeugt, dass in% python Foo ().bar () nicht mehr als eine kurze Hand für Foo.bar (Foo () ) war, die die Instanz als ersten Parameter übergibt. In diesem Beispiel machen die letzten beiden Zeilen (scheinbar) dasselbe:

%Vor%

Aber jetzt habe ich eine Klasse Animal, die eine statische Methode populate () hat, die eine Liste aller dem Menschen bekannten Tiere zurückgibt. Außerdem hat jede Instanz von Animal eine Methode populate (), die die Eigenschaften der Instanz mit zufälligen Werten füllt.

%Vor%

Der Code funktioniert gut, aber was mich verdächtig gemacht hat, war die Tatsache, dass print Animal.populate (qux) die statische Populate-Methode aufgerufen hat (und daher eine Liste zurückgegeben hat und schlechtes Qux nicht gefüllt hat). Offensichtlich ist meine Überzeugung, dass Foo ().bar () nicht mehr als eine kurze Hand für Foo.bar (Foo () ) ist, falsch.

Das wirft verschiedene Fragen für mich auf:

  1. Was passiert, wenn ich Foo ().bar () ?
  2. anrufe?
  3. Was passiert, wenn ich Foo.bar (Foo () ) ?
  4. anrufe?
  5. Gibt es einen inneren Unterschied zwischen den beiden?
  6. Fehle ich ein grundlegendes Konzept von Python?
  7. Wenn Sie eine Klasse schreiben müssen, deren statische Populate-Methode etwas anderes tut als die populate-Methode, die über eine Instanz dieser Klasse aufgerufen wird, was wäre der richtige Weg?

(Ja, es muss derselbe Name sein.)

    
Hyperboreus 01.06.2011, 20:33
quelle

3 Antworten

2

Auf den Unterschied zwischen Foo (). bar (), Foo.bar (Foo ()) und Foo.bar () (als Antwort, weil ich mich gestern angemeldet habe und noch keine Kommentare schreiben kann) - das liegt daran von Python (& lt; 3.0) 's Konzept von' gebundenen 'und' ungebundenen 'Methoden - es erfordert strengstens, dass, außer mit @ staticmethod oder @classmethod, Methodenaufrufen eine Instanz zugeordnet ist. Es gibt keinen leichteren Weg, es zu erklären, als nur etwas, an das man sich erinnern muss. Glücklicherweise hat sich das in Python 3 geändert - das Konzept der "gebundenen" und "ungebundenen" Methoden als getrennte Dinge ist weg, und Foo.bar () funktioniert gut für Ihr Beispiel.

    
lvc 01.06.2011, 23:15
quelle
2

Statische Methoden und Klassenmethoden sind spezielle Deskriptoren . Da die Argumente der __get__() -Methode des Deskriptors sowohl die Klasse als auch jede relevante Instanz enthalten, können sie mit den Argumenten der Methode auf beliebige Weise verschmelzen.

    
Ignacio Vazquez-Abrams 01.06.2011 20:42
quelle
0

qnx.populate() sucht zuerst auf der Instanz qnx nach populate . Wenn dies nicht der Fall ist, wird __mro__ befolgt, bis etwas namens populate gefunden wird.

Animals.populate(qnx) überspringt den ersten Schritt in der obigen Suche

    
John La Rooy 01.06.2011 21:31
quelle

Tags und Links