虽然集成了我以前从未使用过的Django应用程序,但我发现了两种用于在类中定义函数的不同方式。作者似乎非常有意地使用了它们。第一个是我自己经常使用的:
class Dummy(object):
def some_function(self,*args,**kwargs):
do something here
self is the class instance
另一个是我不使用的,主要是因为我不知道何时使用它以及用于什么用途:
class Dummy(object):
@classmethod
def some_function(cls,*args,**kwargs):
do something here
cls refers to what?
在Python文档中,classmethod
装饰器用以下语句解释:
类方法将类作为隐式第一个参数接收,只是就像实例方法接收实例一样。
所以我想cls
指的是Dummy
本身(class
,而不是实例)。我不完全理解为什么会这样,因为我总是可以这样做:
type(self).do_something_with_the_class
这仅仅是为了清楚起见,还是我想念最重要的部分:没有它就无法完成的怪异而令人着迷的事情?
您的猜测是正确的-您了解如何 classmethod
的工作。
这是为什么可以在实例或类上调用这些方法的原因(在两种情况下,都将类对象作为第一个参数传递:]
class Dummy(object):
@classmethod
def some_function(cls,*args,**kwargs):
print cls
#both of these will have exactly the same effect
Dummy.some_function()
Dummy().some_function()
关于在实例上使用这些方法:在实例上调用类方法至少有两个主要用途:
self.some_function()
将以实际的some_function
类型调用self
的版本,而不是出现该调用的类(如果重命名该类,则无需注意);和some_function
的情况下,但单独调用类对象很有用。与staticmethod
的区别]:还有另一种定义不访问实例数据的方法的方法,称为staticmethod
。这样就创建了一个根本不接收隐式第一个参数的方法。因此,将不会传递有关调用它的实例或类的任何信息。
In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1) In [7]: Foo.some_static(1) Out[7]: 2 In [8]: Foo().some_static(1) Out[8]: 2 In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2) In [10]: Bar.some_static(1) Out[10]: 2 In [11]: Bar().some_static(1) Out[11]: 2
我发现它的主要用途是将现有功能(不会收到
self
)改成类(或对象)上的方法。
基本上,当您意识到方法的定义不会被更改或覆盖时,应该使用@classmethod。
如果添加装饰器@classmethod,则意味着您将使该方法成为Java或C ++的静态方法。 (静态方法是一般术语