同时整合我以前没有使用过一个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,这意味着你要作出这样的方法,Java或C ++的静态方法。 (静态方法是一个通用术语,我想;))的Python也@staticmethod。 和类方法和静态方法之间的区别是你是否可以访问类,或使用参数或类名本身静态变量。
class TestMethod(object):
cls_var = 1
@classmethod
def class_method(cls):
cls.cls_var += 1
print cls.cls_var
@staticmethod
def static_method():
TestMethod.cls_var += 1
print TestMethod.cls_var
#call each method from class itself.
TestMethod.class_method()
TestMethod.static_method()
#construct instances
testMethodInst1 = TestMethod()
testMethodInst2 = TestMethod()
#call each method from instances
testMethodInst1.class_method()
testMethodInst2.static_method()
所有这些类增加1 cls.cls_var并打印。
而在相同的范围内或与这些类构造的情况下,使用相同的名称每类是要分享这些方法。 这里只有一个TestMethod.cls_var,也只有一个TestMethod.class_method(),TestMethod.static_method()
而重要的问题。 为什么需要这些方法。
当你做出这个类的一个工厂,或当你必须初始化类只有一次类方法或静态方法是有用的。 像打开文件一次,并且使用进料方法,逐行读取文件中的行。