2009-02-10 21 views
16

Pensé que estaba empezando a controlar la "forma de Python" de la programación. Los métodos de una clase se aceptan a sí mismos como el primer parámetro para referirse a la instancia de la clase cuyo contexto se está llamando al método. El decorador @classmethod se refiere a un método cuya funcionalidad está asociada a la clase, pero que no hace referencia a un instancia específica.¿A qué se refiere el "yo" en un @classmethod?

Entonces, ¿a qué se refiere el primer parámetro de un @classmethod (canónicamente 'self') si el método debe llamarse sin una referencia de instancia?

Respuesta

34

class itself:

un método de clase recibe la clase como primer argumento implícito, al igual que un método de instancia recibe la instancia.

class C: 
    @classmethod 
    def f(cls): 
     print(cls.__name__, type(cls)) 

>>> C.f() 
C <class 'type'> 

y es cls canónicamente, por cierto

+0

+1: Cita del documentación –

0

El objeto de la clase pasa como primer parámetro. Por ejemplo:

class Foo(object): 
    @classmethod 
    def bar(self): 
     return self() 

Devolvería una instancia de la clase Foo.

EDITAR:

Tenga en cuenta que la última línea sería sí() no auto. self devolvería la clase en sí, mientras que self() devolvería una instancia.

+3

Esto es correcto, pero es importante tener en cuenta que 'cls' se usa más comúnmente como primer parámetro de un método de clase. – Lenna

12

El primer parámetro de un classmethod se llama cls por convención y se refiere al objeto de la clase en el que el método se invoca.

>>> class A(object): 
...  @classmethod 
...  def m(cls): 
...   print cls is A 
...   print issubclass(cls, A) 

>>> class B(A): pass 
>>> a = A() 
>>> a.m() 
True 
True 
>>> b = B() 
>>> b.m() 
False 
True 
0

Django hace algunas cosas extrañas con un método de la clase aquí:

class BaseFormSet(StrAndUnicode): 
    """ 
    A collection of instances of the same Form class. 
    """ 
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 
       initial=None, error_class=ErrorList): 
     ... 
     self.prefix = prefix or self.get_default_prefix() 
     ... 

Aunque get_default_prefix se declara de esta manera (en la misma clase):

@classmethod 
    def get_default_prefix(cls): 
     return 'form' 
Cuestiones relacionadas