By default every method created in a class belongs to the object. This means that an instance of the object is required to call a method, and this instance is usually associated with the first parameter of the function (which is called self
). Even the __init__
method, called during object construction, already assumes that the object exists and is accessible through the self
parameter.
class Foo(object):
def __init__(self):
pass # self é o objeto sendo criado
def bar(self, a, b, d):
pass # self é o objeto
foo = Foo()
foo.bar(1,2,3) # implicitamente passa "foo" como 1º argumento para "bar"
fn = foo.bar # fn aqui é um bound method, ligado a "foo"
fn(1,2,3) # Ainda passa "foo" como 1º argumento para "bar"
To create methods that belong to the class, not to the object, you can use the @staticmethod
or @classmethod
decorators. Both are similar, although the former does not refer to the class and the latter does so (similarly to the common method, although in this case it is called cls
instead of self
).
class Foo(object):
@staticmethod
def bar(a, b, c):
pass
@classmethod
def baz(cls, a, b, c):
pass
Foo.bar(1,2,3) # Os argumentos são 1, 2 e 3
Foo.baz(1,2,3) # Os argumentos são Foo, 1, 2 e 3
x = Foo() # Também se pode chamar métodos de classe a partir de uma instância
x.bar(1,2,3) # Os argumentos são 1, 2 e 3
x.baz(1,2,3) # Os argumentos são Foo, 1, 2 e 3
The main difference between @classmethod
and @staticmethod
is that the first can be inherited in order to do something useful. For although both are "inheritable," the former can take the class into consideration in its function, and the latter does not (since it has no reference to the class being used).
class Foo(object):
@staticmethod
def bar():
print Foo # Não há referência à classe, então só se pode acessá-la pelo nome
@classmethod
def baz(cls):
pprint cls # Há referência explícita à classe
class Bar(Foo):
pass
Bar.bar() # imprime Foo
Bar.baz() # imprime Bar
A static / class method can be used for anything, but it makes more sense to use it for things that are related to the class being defined (otherwise, put it in a class, not directly in the module ?). One possibility is to use it as factory , customizing the creation of objects not necessarily of the same class (for example using subclasses when appropriate), or even when the class is the same, varying the parameters received. But there are many others. Personally, I do not recall situations in which a class method was useful to me [in Python], although I vaguely remember having already used it.