When should I use @classmethod and when def method(self)?
在集成我以前没有使用过的django应用程序时,我发现了两种用于在类中定义函数的不同方法。作者似乎非常有意地使用它们。第一个是我自己经常使用的:
1 2 3 4 5 | class Dummy(object): def some_function(self,*args,**kwargs): do something here self is the class instance |
另一个是我不使用的,主要是因为我不知道什么时候使用它,以及为什么:
1 2 3 4 5 6 | class Dummy(object): @classmethod def some_function(cls,*args,**kwargs): do something here cls refers to what? |
在python文档中,
A class method receives the class as implicit first argument, just
like an instance method receives the instance.
所以我猜
1 | type(self).do_something_with_the_class |
这仅仅是为了清晰起见,还是我错过了最重要的部分:没有它就无法完成的恐怖而迷人的事情?
你的猜测是正确的——你知道
为什么可以在实例或类上同时调用这些方法(在这两种情况下,类对象都将作为第一个参数传递):
1 2 3 4 5 6 7 8 9 | 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() |
在实例上使用这些方法:在实例上调用ClassMethod至少有两种主要用途:
与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
我发现它的主要用途是将现有函数(它不希望接收
如果你添加了装饰器@ Cube方法,那就意味着你要把这个方法作为Java或C++的静态方法。(我想静态方法是一个通用术语;)python也有@staticmethod。ClassMethod和StaticMethod的区别在于使用参数或类名本身访问类或静态变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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() |
所有这些类都将cls.cls_var增加1并打印出来。
在同一个作用域或用这些类构造的实例上使用相同名称的每个类都将共享这些方法。只有一个testmethod.cls_var而且只有一个testmethod.class_method(),testmethod.static_method()。
以及重要问题。为什么需要这些方法。
类方法或静态方法在将该类作为工厂时是有用的。或者当你必须只初始化你的班级一次。如打开文件一次,并使用FIX方法逐行读取文件。