classmethod在这段代码中做了什么?

zjm*_*126 46 python

在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)
Run Code Online (Sandbox Code Playgroud)

我不知道classmethod这段代码中的内容是什么.有人可以解释它的作用以及如何使用它吗?

Ale*_*lli 170

classmethod 是一个描述符,包装一个函数,你可以在一个类或(等效地)一个实例上调用结果对象:

>>> 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'>,)
Run Code Online (Sandbox Code Playgroud)

如您所见,无论是直接定义还是使用装饰器语法定义它,无论是在类还是实例上调用它,classmethod总是将类作为其第一个参数接收.

classmethod的主要用途之一是定义"替代构造函数":

>>> 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')
Run Code Online (Sandbox Code Playgroud)

现在,如果你是子类y,则classmethod继续工作,例如:

>>> class k(y):
...   def __repr__(self):
...     return 'k(%r)' % self.s.upper()
...
>>> k1 = k.fromlist(['za','bu'])
>>> k1
k('ZA,BU')
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个替代构造函数,这是一个工厂方法. (9认同)
  • @ t3chb0t,它是一种工厂方法,用作替代构造函数。 (3认同)
  • 同意@t3chb0t,这是另一种[对象的字符串表示](https://docs.python.org/3/reference/datamodel.html#object.__repr__)。本例中 y 类和 k 类的对象似乎具有相同的构造。 (2认同)

Ned*_*der 8

它可以在类而不是对象上调用方法:

class MyClass(object):
    def _new_instance(cls, blah):
        pass
    _new_instance = classmethod(_new_instance)

MyClass._new_instance("blah")
Run Code Online (Sandbox Code Playgroud)

  • 它也更常用作装饰器:`@classmethod def _new_instance(cls,blah):` (3认同)