source:
Maybe a bit of example code will help: Notice the difference in the call signatures of
foo
, class_foo
and static_foo
:class A(object):
def foo(self,x):
print "executing foo(%s,%s)"%(self,x)
@classmethod
def class_foo(cls,x):
print "executing class_foo(%s,%s)"%(cls,x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)"%x
a=A()
Below is the usual way an object instance calls a method. The object instance,
a
, is implicitly passed as the first argument.a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)
With classmethods, the class of the object instance is implicitly passed as the first argument instead of
self
.a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
You can also call
class_foo
using the class. In fact, if you define something to be a classmethod, it is probably because you intend to call it from the class rather than from a class instance. A.foo(1)
would have raised a TypeError, but A.class_foo(1)
works just fine:A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
One use people have found for class methods is to create inheritable alternative constructors.(see far below for an example)
With staticmethods, neither
self
(the object instance) nor cls
(the class) is implicitly passed as the first argument. They behave like plain functions except that you can call them from an instance or the class:a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)
Staticmethods are used to group functions which have some logical connection with a class to the class.
foo
is just a function, but when you call a.foo
you don't just get the function, you get a "curried" version of the function with the object instance a
bound as the first argument to the function. foo
expects 2 arguments, while a.foo
only expects 1 argument.a
is bound to foo
. That is what is meant by the term "bound" below:print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
With
a.class_foo
, a
is not bound to class_foo
, rather the class A
is bound to class_foo
.print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>
Here, with a staticmethod, even though it is a method,
a.static_foo
just returns a good 'ole function with no arguments bound. static_foo
expects 1 argument, and a.static_foo
expects 1 argument too.print(a.static_foo)
# <function static_foo at 0xb7d479cc>
|
I don't understand what's the catch for using staticmethod. we can just use a simple outside-of-class function. – Alcott Sep 19 '11 at 3:08
| ||
|
@Alcott: You might want to move a function into a class because it logically belongs with the class. In the Python source code (e.g. multiprocessing,turtle,dist-packages), it is used to "hide" single-underscore "private" functions from the module namespace. Its use, though, is highly concentrated in just a few modules -- perhaps an indication that it is mainly a stylistic thing. Though I could not find any example of this,
@staticmethod might help organize your code by being overridable by subclasses. Without it you'd have variants of the function floating around in the module namespace. – unutbu Sep 19 '11 at 10:34 | ||
|
@Alcott: as unutbu said, static methods are an organization/stylistic feature. Sometimes a module have many classes, and some helper functions are logically tied to a a given class and not to the others, so it makes sense not to "pollute" the module with many "free functions", and it is better to use a static method than relying on the poor style of mixing classes and function defs together in code just to show they are "related" – MestreLion May 3 '12 at 9:55
| ||
|
@unutbu: You should however delete that Guido quote: It was from an early draft of python 2.2 release notes, and it was changed in 2.2.3 to:
However, class methods are still useful in other places, for example, to program inheritable alternate constructors. Even the original quote is very misleading, as he only said that the python distribuition does not use classmethod . But just because python itself don't use a given feature, it doesn't mean it's a useless feature. Think about complex numbers or evensqrt: python itself may not use either, but it's far from being useless to offer – MestreLion May 3 '12 at 10:44 | ||
|
-----------------------------------------------------------------------------------------------------------------
source:
You can't have two constructors in one class.
Constructors have to be named
__init__ . And, unlike Java, Python doesn't allow overloading functions or methods by the type of their arguments. So, if you had two constructors, they would both be the same function.
There are a few ways around this.
Use
@classmethod s as alternate constructors:
A simple example from the standard library is
datetime.datetime , which can be constructed with now , fromtimestamp , or a few other alternate constructors, besides the default.
Use default-valued, keyword-only, and/or variable-argument parameters to make a single constructor that can be called different ways:
int is an example of this: You can create it from a string and a base, or from a single argument that knows how to convert itself to an integer.
Create subclasses that each have different constructors:
In any of these cases, you can factor out commonalities into a single "base" initializer. For example:
Of course in no case is it possible to have breakfast without spam.
|