2009-03-28 5 views
26

Ex.Est-ce une mauvaise forme d'appeler un classmethod comme une méthode d'une instance?

Si j'ai quelque chose comme ceci:

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

Cela fonctionne:

c = C() 

c.f(2) 
4 

Mais est-ce une mauvaise forme? Si je n'appeler

C.f() 

ou

c.__class__.f() 

De toute évidence, cela ne ferait que donner un sens dans les cas où f ne réagit pas avec l'auto/Cls attend que ce soit la classe.

?

+1

OT, mais le type préfèrent (c) à c .__ class__ – Miles

Répondre

25

Si vous êtes tenté d'appeler une méthode de classe à partir d'une instance, vous n'avez probablement pas besoin d'une méthode de classe. Dans l'exemple que vous avez donné une méthode statique serait plus approprié précisément à cause de votre dernière remarque (pas d'interaction self/cls).

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

cette façon, il est "bonne forme" de faire les deux

c = C() 
c.f(2) 

et

C.f(2) 
+0

Oui mais que faire si vous avez vraiment besoin d'une méthode de classe? – frnhr

4

Il s'agit principalement d'une apparence déroutante. Si j'utilisais ta classe et que je voyais ça, je me demandais quelles autres surprises il y avait, ça ressemblait à un mauvais design.

Y at-il une raison pour laquelle ce n'est pas seulement une méthode statique?

2

C.f() est plus claire que c_instance.f(), et c_instance.__class__.f() est juste moche. Puisque la clarté et la beauté sont des caractéristiques chères dans la communauté python, j'aurais tendance à dire que C.f() est la meilleure route.

Y a-t-il une raison particulière pour laquelle vous voulez même l'appeler de l'une ou l'autre façon?

+4

Le nom de la classe (dans ce cas "C") pourrait changer si ... –

3

Si vous avez déjà une instance de C, pourquoi avez-vous besoin de f() pour être une méthode de classe? Non seulement c'est une mauvaise forme, mais ce n'est généralement pas nécessaire. Quelqu'un sur le net dit: "Ceci est mauvais parce qu'il donne l'impression que certaines variables d'instance dans l'objet sont utilisées, mais ce n'est pas le cas."

Bien que, à la page 484 de learning python notes que vous pouvez appeler la méthode ou l'autre manière, et il sera exactement la même chose aussi longtemps que vous passez la même instance dans.

+4

Vous n'avez pas besoin de classmethod-on-instance pour l'exemple de code donné, mais si vous avez commencé à sous-classer C, vous pourriez le faire. – bobince

9

Je ne me souviens pas en utilisant un classmethod comme celui-ci de l'extérieur de la classe, mais il est certainement acceptable pour une méthode d'instance d'appeler une méthode de classe sur elle-même (par exemple self.foo()foo est une méthode de classe). Cela s'assure que l'héritage agit comme prévu et appellera .foo() dans la sous-classe à droite au lieu de la classe de base.

Questions connexes