2009-03-28 6 views
26

Ex.Ist es eine schlechte Form, eine Klassenmethode als Methode von einer Instanz aufzurufen?

Wenn ich so etwas wie dieses:

class C(object): 
    @classmethod 
    def f(cls, x): 
     return x + x 

Dies funktioniert:

c = C() 

c.f(2) 
4 

Aber ist das schlechte Form? Sollte ich nenne nur

C.f() 

oder

c.__class__.f() 

Offensichtlich ist dies nur dann sinnvoll in Fällen machen würde, wenn f nicht mit sich selbst in Wechselwirkung tritt/cls es Klasse zu erwarten.

?

+1

OT zu tun, aber es vorziehen, Typ (c) bis c .__ class__ – Miles

Antwort

25

Wenn Sie versucht sind, eine Klassenmethode von einer Instanz aufzurufen, benötigen Sie wahrscheinlich keine Klassenmethode.

In dem Beispiel, das Sie angegeben haben, wäre eine statische Methode aufgrund Ihrer letzten Bemerkung passender (keine self/cls-Interaktion).

class C(object): 
    @staticmethod 
    def f(x): 
     return x + x 

diese Art und Weise es "gute Form" ist sowohl

c = C() 
c.f(2) 

und

C.f(2) 
+0

Ja, aber wenn Sie wirklich eine Klassenmethode brauchen? – frnhr

4

Es ist hauptsächlich nur verwirrend zu suchen. Wenn ich Ihre Klasse benutzen würde und dies sehen würde, würde ich mich wundern, welche anderen Überraschungen da drin sind, es sieht einfach nach schlechtem Design aus.

Gibt es einen Grund, dass es nicht nur eine statische Methode ist?

2

C.f() ist klarer als c_instance.f(), und c_instance.__class__.f() ist nur hässlich. Da Klarheit und Schönheit in der Python-Community sehr beliebt sind, würde ich sagen, dass C.f() der beste Weg ist.

Gibt es einen bestimmten Grund, warum Sie es auch auf andere Weise aufrufen möchten?

+4

Der Name der Klasse (in diesem Fall könnte sich "C" jedoch ändern ... –

3

Wenn Sie bereits eine Instanz von C haben, warum brauchen Sie f() als Klassenmethode? Es ist nicht nur schlechte Form, es ist normalerweise nicht notwendig. Jemand im Netz sagt: "Das ist schlecht, weil es den Eindruck erweckt, dass einige Instanzvariablen im Objekt verwendet werden, aber das ist nicht der Fall."

Obwohl Seite 484 von learning python stellt fest, dass Sie die Methode so oder so nennen kann, und es wird genau so lange das gleiche sein, wie Sie die gleiche Instanz passieren in.

+4

Sie benötigen keine classmethod-on-Instanz für den angegebenen Beispielcode, aber wenn Sie mit der Unterklasse C begonnen haben, könnten Sie das tun. – bobince

9

Ich erinnere mich nicht ein Class wie folgt aus von außerhalb der Klasse, aber es ist sicherlich in Ordnung, wenn eine Instanzmethode eine Klassenmethode für sich selbst aufruft (z. B. self.foo(), wobei foo eine Klassenmethode ist). Dies stellt sicher, dass die Vererbung wie erwartet funktioniert, und ruft .foo() in der rechten Unterklasse anstelle der Basisklasse auf.