问题
While integrating a Django app I have not used before, I found two different ways used to define functions in classes. The author seems to use them both very intentionally. The first one is one I myself use a lot:
class Dummy(object):
def some_function(self,*args,**kwargs):
do something here
self is the class instance
The other one is one I do not use, mostly because I do not understand when to use it, and what for:
class Dummy(object):
@classmethod
def some_function(cls,*args,**kwargs):
do something here
cls refers to what?
In the Python docs the classmethod
decorator is explained with this sentence:
A class method receives the class as implicit first argument, just like an instance method receives the instance.
So I guess cls
refers to Dummy
itself (the class
, not the instance). I do not exactly understand why this exists, because I could always do this:
type(self).do_something_with_the_class
Is this just for the sake of clarity, or did I miss the most important part: spooky and fascinating things that couldn't be done without it?
回答1:
Your guess is correct - you understand how classmethod
s work.
The why is that these methods can be called both on an instance OR on the class (in both cases, the class object will be passed as the first argument):
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()
On the use of these on instances: There are at least two main uses for calling a classmethod on an instance:
self.some_function()
will call the version ofsome_function
on the actual type ofself
, rather than the class in which that call happens to appear (and won't need attention if the class is renamed); and- In cases where
some_function
is necessary to implement some protocol, but is useful to call on the class object alone.
The difference with staticmethod
: There is another way of defining methods that don't access instance data, called staticmethod
. That creates a method which does not receive an implicit first argument at all; accordingly it won't be passed any information about the instance or class on which it was called.
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
The main use I've found for it is to adapt an existing function (which doesn't expect to receive a self
) to be a method on a class (or object).
回答2:
If you add decorator @classmethod, That means you are going to make that method as static method of java or C++. ( static method is a general term I guess ;) ) Python also has @staticmethod. and difference between classmethod and staticmethod is whether you can access to class or static variable using argument or classname itself.
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()
all those classes increase cls.cls_var by 1 and print it.
And every classes using same name on same scope or instances constructed with these class is going to share those methods. There's only one TestMethod.cls_var and also there's only one TestMethod.class_method() , TestMethod.static_method()
And important question. why these method would be needed.
classmethod or staticmethod is useful when you make that class as a factory or when you have to initialize your class only once. like open file once, and using feed method to read the file line by line.
来源:https://stackoverflow.com/questions/10586787/when-should-i-use-classmethod-and-when-def-methodself