are - que es @classmethod en python
¿Qué hace classmethod en este código? (2)
Hace posible llamar al método en la clase en lugar de un objeto:
class MyClass(object):
def _new_instance(cls, blah):
pass
_new_instance = classmethod(_new_instance)
MyClass._new_instance("blah")
En django.utils.tree.py:
def _new_instance(cls, children=None, connector=None, negated=False):
obj = Node(children, connector, negated)
obj.__class__ = cls
return obj
_new_instance = classmethod(_new_instance)
No sé lo que hace classmethod
en este ejemplo de código. ¿Alguien puede explicar lo que hace y cómo usarlo?
classmethod
es un descriptor, que envuelve una función, y puede llamar al objeto resultante en una clase o (equivalentemente) a una instancia de la misma:
>>> class x(object):
... def c1(*args): print ''c1'', args
... c1 = classmethod(c1)
... @classmethod
... def c2(*args): print ''c2'', args
...
>>> inst = x()
>>> x.c1()
c1 (<class ''__main__.x''>,)
>>> x.c2()
c2 (<class ''__main__.x''>,)
>>> inst.c1()
c1 (<class ''__main__.x''>,)
>>> inst.c2()
c2 (<class ''__main__.x''>,)
Como puede ver, ya sea que lo defina directamente o con la sintaxis del decorador, y si lo llama en la clase o la instancia, el classmethod
la clase siempre recibe la clase como su primer argumento.
Uno de los principales usos de classmethod es definir "constructores alternativos":
>>> class y(object):
... def __init__(self, astring):
... self.s = astring
... @classmethod
... def fromlist(cls, alist):
... x = cls('''')
... x.s = '',''.join(str(s) for s in alist)
... return x
... def __repr__(self):
... return ''y(%r)'' % self.s
...
>>> y1 = y(''xx'')
>>> y1
y(''xx'')
>>> y2 = y.fromlist(range(3))
>>> y2
y(''0,1,2'')
Ahora bien, si subclases y
, el método de clase sigue funcionando, por ejemplo:
>>> class k(y):
... def __repr__(self):
... return ''k(%r)'' % self.s.upper()
...
>>> k1 = k.fromlist([''za'',''bu''])
>>> k1
k(''ZA,BU'')