@classmethod
和 python 中的“经典”方法有什么区别,
我什么时候应该使用@classmethod
,什么时候应该在 python 中使用“经典”方法。classmethod 是否必须是引用类的方法(我的意思是它只是处理类的方法)?
我知道@staticmethod 和经典方法 Thx 之间有什么区别
@classmethod
和 python 中的“经典”方法有什么区别,
我什么时候应该使用@classmethod
,什么时候应该在 python 中使用“经典”方法。classmethod 是否必须是引用类的方法(我的意思是它只是处理类的方法)?
我知道@staticmethod 和经典方法 Thx 之间有什么区别
如果你在一个类中定义了一个方法,它会以一种特殊的方式被处理:对它的访问会将它包装在一个特殊的对象中,该对象会修改调用参数以包含self
对被引用对象的引用:
class A(object):
def f(self):
pass
a = A()
a.f()
这个调用a.f
实际上要求f
(通过描述符 协议)一个对象真正返回。然后这个对象在没有参数的情况下被调用,并将调用转移到 real f
,添加a
在前面。
所以真正做的是用作为参数a.f()
调用原始函数。f
(a)
为了防止这种情况,我们可以包装函数
@staticmethod
装饰师,@classmethod
装饰师,@staticmethod
把它变成一个对象,当被问到时,它会改变参数传递行为,以便它与调用 original 的意图相匹配f
:
class A(object):
def method(self):
pass
@staticmethod
def stmethod():
pass
@classmethod
def clmethod(cls):
pass
a = A()
a.method() # the "function inside" gets told about a
A.method() # doesn't work because there is no reference to the needed object
a.clmethod() # the "function inside" gets told about a's class, A
A.clmethod() # works as well, because we only need the classgets told about a's class, A
a.stmethod() # the "function inside" gets told nothing about anything
A.stmethod() # works as well
因此@classmethod
,@staticmethod
它们的共同点是“不关心”它们被调用的具体对象;不同的是,@staticmethod
它根本不想知道任何关于它的东西,而@classmethod
想知道它的类。
所以后者获取使用的对象是一个实例的类对象。在这种情况下只需替换self
为。cls
现在,什么时候用什么?
好吧,这很容易处理:
self
,您显然需要一个实例方法。self
,但想了解其类,请使用@classmethod
. 例如,工厂方法可能就是这种情况。datetime.datetime.now()
就是这样一个例子:你可以通过它的类或者通过一个实例来调用它,但是它会创建一个具有完全不同数据的新实例。我什至用它们一次来自动生成给定类的子类。self
也不需要cls
,则使用@staticmethod
. 这也可以用于工厂方法,如果它们不需要关心子类化。假设您有一个Car
代表Car
系统中实体的类。
Aclassmethod
是一种适用于Car
不在任何Car
' 实例上的类的方法。因此,用 装饰的函数@classmethod
(通常称为cls
)的第一个参数是类本身。例子:
class Car(object):
colour = 'red'
@classmethod
def blue_cars(cls):
# cls is the Car class
# return all blue cars by looping over cls instances
函数作用于类的特定实例;通常调用的第一个参数self
是实例本身:
def get_colour(self):
return self.colour
总结一下:
用于classmethod
实现适用于整个类(而不是特定类实例)的方法:
Car.blue_cars()
使用实例方法来实现适用于特定实例的方法:
my_car = Car(colour='red')
my_car.get_colour() # should return 'red'
@classmethod
将类作为第一个参数,而函数采用类的实例
>>> class Test(object):
... def func(self):
... print self
... @classmethod
... def meth(self):
... print self
>>> t = Test()
>>> t.func()
<__main__.Test object at 0x00000000027238D0>
>>> t.meth()
<class '__main__.Test'>
我故意使用self
了参数,meth
所以它的语法非常接近func
. 但通常你最好cls
用作参数:
... @classmethod
... def meth(cls):
... print cls