2009-03-28 18 views
26

Ej.¿Es malo llamar a un método de clase como un método de una instancia?

Si tengo algo como esto:

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

Esto funcionará:

c = C() 

c.f(2) 
4 

Pero es tan mala forma? ¿Debo llamar solamente

C.f() 

o

c.__class__.f() 

Obviamente, esto sólo tendría sentido en los casos en que f no interactúa con auto/CLS esperaba que fuera de clase.

?

+1

OT, pero prefieren el tipo (c) ac .__ class__ – Miles

Respuesta

25

Si tiene la tentación de llamar a un método de clase desde una instancia, probablemente no necesite un método de clase.

En el ejemplo que proporcionó un método estático sería más apropiado precisamente por su última observación (sin interacción self/cls).

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

esta manera es "buena forma" de hacer ambas cosas

c = C() 
c.f(2) 

y

C.f(2) 
+0

Sí, pero ¿y si realmente necesitas un método de clase? – frnhr

4

Es principalmente una apariencia confusa. Si estuviera usando tu clase y viera esto, me preguntaría qué otras sorpresas hay, parece un mal diseño.

¿Hay alguna razón por la que no sea solo un método estático?

2

C.f() es más claro que c_instance.f(), y c_instance.__class__.f() es feo. Dado que la claridad y la belleza son características muy queridas en la comunidad de pitones, tendería a decir que C.f() es la mejor ruta.

¿Hay alguna razón en particular por la que desee llamar de alguna de las otras maneras?

+4

El nombre de la clase (en este caso 'C') podría cambiar sin embargo ... –

3

Si ya tiene una instancia de C, ¿por qué necesita que f() sea un método de clase? No solo es mala forma, por lo general no es necesario. Alguien en la red dice: "Esto es malo porque crea la impresión de que se usan algunas variables de instancia en el objeto, pero este no es el caso".

Aunque, en la página 484 de learning python notas que se puede llamar al método de cualquier manera y será exactamente el mismo que el tiempo que se pasa en la misma instancia.

+4

No necesita classmethod-on-instance para el código de ejemplo dado, pero si comenzó la subclasificación de C, podría hacerlo. – bobince

9

No recuerdo usando un classmethod como esto desde fuera de la clase, pero ciertamente está bien que un método de instancia llame a un método de clase sobre sí mismo (por ejemplo, self.foo(), donde foo es un método de clase). Esto asegura que la herencia actúa como se espera y llamará al .foo() en la subclase derecha en lugar de a la clase base.

Cuestiones relacionadas