Quelle est la différence entre une fonction décorée avec @staticmethod
et une fonction décorée avec @classmethod
?
Peut-être qu'un exemple de code aidera: Notez la différence entre les signatures d'appel de foo
, class_foo
et 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()
Ci-dessous, la manière habituelle pour une instance d'objet d'appeler une méthode. L'instance d'objet, a
, est implicitement passée en tant que premier argument.
a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)
Avec classmethods , la classe de l'instance d'objet est implicitement passée comme premier argument à la place de self
.
a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
Vous pouvez également appeler class_foo
à l'aide de la classe. En fait, si vous définissez quelque chose comme étant une méthode de classe, c'est probablement parce que vous avez l'intention de l'appeler depuis la classe plutôt que depuis une instance de classe. A.foo(1)
aurait généré une erreur TypeError, mais A.class_foo(1)
fonctionne parfaitement:
A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
Une utilisation que les utilisateurs ont trouvée pour les méthodes de classe consiste à créer constructeurs alternatifs héritables .
Avec staticmethods , ni self
(l'instance de l'objet) ni cls
(la classe) n'est implicitement passé comme premier argument. Ils se comportent comme des fonctions simples, sauf que vous pouvez les appeler à partir d'une instance ou de la classe:
a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)
Les méthodes statiques sont utilisées pour regrouper des fonctions qui ont une connexion logique avec une classe à la classe.
foo
n'est qu'une fonction, mais lorsque vous appelez a.foo
vous n'obtenez pas seulement la fonction, vous obtenez une version "partiellement appliquée" de la fonction avec l'instance d'objet a
liée comme le premier argument de la fonction. foo
attend 2 arguments, alors que a.foo
n'attend qu'un argument.
a
est lié à foo
. C'est ce que l'on entend par le terme "lié" ci-dessous:
print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
Avec a.class_foo
, a
n'est pas lié à class_foo
, mais la classe A
est liée à class_foo
.
print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>
Ici, avec une méthode static, même s’il s’agit d’une méthode, a.static_foo
ne retourne qu’une bonne fonction ole sans argument lié. static_foo
attend 1 argument et a.static_foo
attend 1 argument également.
print(a.static_foo)
# <function static_foo at 0xb7d479cc>
Et bien sûr, la même chose se produit lorsque vous appelez static_foo
avec la classe A
à la place.
print(A.static_foo)
# <function static_foo at 0xb7d479cc>
staticmethod est une méthode qui ignore tout de la classe ou de l'instance sur laquelle elle a été appelée. Il récupère simplement les arguments qui ont été passés, sans premier argument implicite. Il est pratiquement inutile dans Python - vous pouvez simplement utiliser une fonction de module au lieu d'une méthode statique.
Un classmethod, en revanche, est une méthode qui transmet en tant que premier argument la classe sur laquelle il a été appelé ou la classe de l'instance sur laquelle il a été appelé. Ceci est utile lorsque vous voulez que la méthode soit une fabrique pour la classe: étant donné qu'elle obtient comme premier argument la classe sur laquelle elle a été appelée, vous pouvez toujours instancier la bonne classe, même lorsque des sous-classes sont impliquées. Observez par exemple comment dict.fromkeys()
, une méthode de classe, renvoie une instance de la sous-classe lorsqu'elle est appelée dans une sous-classe:
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
Fondamentalement, @classmethod
crée une méthode dont le premier argument est la classe à partir de laquelle elle est appelée (plutôt que l'instance de la classe). @staticmethod
n'a pas d'argument implicite.
Officiel python docs:
Une méthode de classe reçoit la classe en tant que premier argument implicite, tout comme une méthode d'instance reçoit l'instance. Pour déclarer une méthode de classe, utilisez cet idiome:
class C: @classmethod def f(cls, arg1, arg2, ...): ...
La forme
@classmethod
est une fonction décorateur - voir la description des définitions de fonctions dans Fonction définitions pour plus de détails.Il peut être appelé soit sur la classe (telle que
C.f()
), soit sur une instance (telle queC().f()
). L'instance est ignorée à l'exception de sa classe. Si une méthode de classe est appelée pour une classe dérivée, l'objet de classe dérivée est passé en tant que premier argument implicite.Les méthodes de classe sont différentes des méthodes statiques C++ ou Java. Si vous le souhaitez, voir
staticmethod()
dans cette section.
Une méthode statique ne reçoit pas de premier argument implicite. Pour déclarer une méthode statique, utilisez cet idiome:
class C: @staticmethod def f(arg1, arg2, ...): ...
La forme
@staticmethod
est une fonction décorateur - voir la description des définitions de fonctions dans Fonction définitions pour plus de détails.Il peut être appelé soit sur la classe (telle que
C.f()
), soit sur une instance (telle queC().f()
). L'instance est ignorée à l'exception de sa classe.Les méthodes statiques dans Python sont similaires à celles trouvées dans Java ou C++. Pour un concept plus avancé, voir
classmethod()
dans cette section.
Ici est un court article sur cette question
La fonction @staticmethod n'est rien de plus qu'une fonction définie dans une classe. Il est appelable sans instancier d'abord la classe. Sa définition est immuable par héritage.
La fonction @classmethod peut également être appelée sans instancier la classe, mais sa définition suit la classe Sub, et non la classe Parent, via l'héritage. C’est parce que le premier argument de la fonction @classmethod doit toujours être cls (classe).
Pour décider d'utiliser @ staticmethod ou @ classmethod , vous devez regarder à l'intérieur de votre méthode. Si votre méthode accède à d'autres variables/méthodes de votre classe, utilisez @classmethod . Par contre, si votre méthode ne touche aucune autre partie de la classe, utilisez @staticmethod.
class Apple:
_counter = 0
@staticmethod
def about_Apple():
print('Apple is good for you.')
# note you can still access other member of the class
# but you have to use the class instance
# which is not very Nice, because you have repeat yourself
#
# For example:
# @staticmethod
# print('Number of apples have been juiced: %s' % Apple._counter)
#
# @classmethod
# print('Number of apples have been juiced: %s' % cls._counter)
#
# @classmethod is especially useful when you move your function to other class,
# you don't have to rename the class reference
@classmethod
def make_Apple_juice(cls, number_of_apples):
print('Make juice:')
for i in range(number_of_apples):
cls._juice_this(i)
@classmethod
def _juice_this(cls, Apple):
print('Juicing %d...' % Apple)
cls._counter += 1
Quelle est la différence entre @staticmethod et @classmethod en Python?
Vous avez peut-être vu le code Python comme ce pseudocode, qui illustre les signatures des différents types de méthodes et fournit une chaîne de documentation pour expliquer chacun:
class Foo(object):
def a_normal_instance_method(self, arg_1, kwarg_2=None):
'''
Return a value that is a function of the instance with its
attributes, and other arguments such as arg_1 and kwarg2
'''
@staticmethod
def a_static_method(arg_0):
'''
Return a value that is a function of arg_0. It does not know the
instance or class it is called from.
'''
@classmethod
def a_class_method(cls, arg1):
'''
Return a value that is a function of the class and other arguments.
respects subclassing, it is called with the class it is called from.
'''
Je vais d'abord expliquer a_normal_instance_method
. Cela s'appelle précisément une " méthode d'instance ". Lorsqu'une méthode d'instance est utilisée, elle est utilisée comme fonction partielle (par opposition à une fonction totale définie pour toutes les valeurs affichées dans le code source), c'est-à-dire que le premier des arguments est utilisé comme instance du objet, avec tous ses attributs donnés. L'instance de l'objet y est liée et doit être appelée à partir d'une instance de l'objet. En règle générale, il aura accès à divers attributs de l'instance.
Par exemple, ceci est une instance d'une chaîne:
', '
si nous utilisons la méthode d'instance, join
, sur cette chaîne, pour en joindre une autre, il s'agit bien évidemment d'une fonction de l'instance, en plus d'être une fonction de la liste, que ['a', 'b', 'c']
:
>>> ', '.join(['a', 'b', 'c'])
'a, b, c'
Les méthodes d'instance peuvent être liées via une recherche en pointillé pour une utilisation ultérieure.
Par exemple, cela lie la méthode str.join
à l'instance ':'
:
>>> join_with_colons = ':'.join
Et plus tard, nous pouvons l’utiliser comme une fonction à laquelle le premier argument est déjà lié. De cette façon, cela fonctionne comme une fonction partielle sur l'instance:
>>> join_with_colons('abcde')
'a:b:c:d:e'
>>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF'])
'FF:FF:FF:FF:FF:FF'
La méthode statique ne pas prend l'instance en argument.
C'est très similaire à une fonction de niveau module.
Cependant, une fonction de niveau module doit résider dans le module et être spécialement importée vers d'autres emplacements où elle est utilisée.
Cependant, s'il est attaché à l'objet, il le suivra facilement lors de l'importation et de l'héritage.
Un exemple de méthode statique est str.maketrans
, déplacé du module string
dans Python 3. Cela rend une table de traduction appropriée à la consommation par str.translate
. Cela semble plutôt idiot de l'utiliser à partir d'une instance d'une chaîne, comme illustré ci-dessous, mais importer la fonction à partir du module string
est plutôt maladroit, et il est agréable de pouvoir l'appeler de la classe, comme dans str.maketrans
# demonstrate same function whether called from instance or not:
>>> ', '.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
>>> str.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
Dans python 2, vous devez importer cette fonction à partir du module de chaîne de moins en moins utile:
>>> import string
>>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc'))
'abcDEFG'
Une méthode de classe est similaire à une méthode d'instance en ce qu'elle prend un premier argument implicite, mais au lieu de prendre l'instance, elle prend la classe. Fréquemment, ils sont utilisés comme constructeurs alternatifs pour un meilleur usage sémantique et supporteront l'héritage.
L'exemple le plus canonique d'une méthode de classe intégrée est dict.fromkeys
. Il est utilisé en tant que constructeur alternatif de dict (convient bien lorsque vous connaissez vos clés et souhaitez une valeur par défaut pour celles-ci.)
>>> dict.fromkeys(['a', 'b', 'c'])
{'c': None, 'b': None, 'a': None}
Lorsque nous sous-classe dict, nous pouvons utiliser le même constructeur, ce qui crée une instance de la sous-classe.
>>> class MyDict(dict): 'A dict subclass, use to demo classmethods'
>>> md = MyDict.fromkeys(['a', 'b', 'c'])
>>> md
{'a': None, 'c': None, 'b': None}
>>> type(md)
<class '__main__.MyDict'>
Voir le code source de pandas pour d'autres exemples similaires de constructeurs alternatifs, et voir aussi la documentation officielle Python sur classmethod
et staticmethod
=.
J'ai commencé à apprendre le langage de programmation avec C++, puis Java, puis Python. Cette question m'a donc beaucoup dérangé jusqu'à ce que je comprenne l'utilisation simple de chacun.
Méthode de classe: Python contrairement à Java et C++ n'a pas de surcharge de constructeur. Et pour cela, vous pouvez utiliser classmethod
. L'exemple suivant expliquera ceci
Considérons que nous avons une classe Person
qui prend deux arguments first_name
et last_name
et crée l'instance de Person
.
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
Maintenant, si l'exigence vient où vous devez créer une classe en utilisant un seul nom, juste un first_name
, vous ne pouvez pas faire quelque chose comme ça en Python.
Cela vous donnera une erreur lorsque vous essayez de créer un objet (instance).
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def __init__(self, first_name):
self.first_name = first_name
Cependant, vous pouvez obtenir la même chose en utilisant @classmethod
comme mentionné ci-dessous
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@classmethod
def get_person(cls, first_name):
return cls(first_name, "")
Static Method: Ceci est assez simple, il n'est pas lié à une instance ou à une classe et vous pouvez simplement appeler cela en utilisant le nom de la classe.
Supposons que dans l'exemple ci-dessus, vous avez besoin d'une validation selon laquelle first_name
ne doit pas dépasser 20 caractères. Vous pouvez simplement le faire.
@staticmethod
def validate_name(name):
return len(name) <= 20
et vous pouvez simplement appeler en utilisant class name
Person.validate_name("Gaurang Shah")
@decorators ont été ajoutés à python 2.4 Si vous utilisez python <2.4, vous pouvez utiliser les fonctions classmethod () et staticmethod ().
Par exemple, si vous souhaitez créer une méthode fabrique (une fonction renvoyant une instance d'une implémentation différente d'une classe en fonction de l'argument qu'elle obtient), vous pouvez effectuer les opérations suivantes:
class Cluster(object):
def _is_cluster_for(cls, name):
"""
see if this class is the cluster with this name
this is a classmethod
"""
return cls.__== name
_is_cluster_for = classmethod(_is_cluster_for)
#static method
def getCluster(name):
"""
static factory method, should be in Cluster class
returns a cluster object for the given name
"""
for cls in Cluster.__subclasses__():
if cls._is_cluster_for(name):
return cls()
getCluster = staticmethod(getCluster)
Notez également qu'il s'agit d'un bon exemple d'utilisation d'une méthode de classe et d'une méthode statique. La méthode statique appartient clairement à la classe car elle utilise la classe Cluster en interne. La méthode de classe n'a besoin que d'informations sur la classe et pas d'instance de l'objet.
Un autre avantage de transformer la méthode _is_cluster_for
en méthode de classe est une méthode permettant à une sous-classe de modifier son implémentation, peut-être parce qu'elle est assez générique et qu'elle peut gérer plusieurs types de grappes. être assez.
Je pense qu'une meilleure question est "Quand utiliseriez-vous @classmethod vs @staticmethod?"
@classmethod vous permet d'accéder facilement aux membres privés associés à la définition de classe. c'est un excellent moyen de créer des singletons ou des classes d'usine contrôlant le nombre d'occurrences des objets créés.
@staticmethod fournit des gains de performance marginaux, mais je n'ai pas encore vu l'utilisation productive d'une méthode statique dans une classe qui ne pourrait pas être réalisée en tant que fonction autonome en dehors de la classe.
Méthodes statiques:
Avantages des méthodes statiques:
Plus pratique d’importer que des fonctions de niveau module puisque chaque méthode n’a pas besoin d’être importée spécialement
@staticmethod
def some_static_method(*args, **kwds):
pass
Méthodes de classe:
Celles-ci sont créées avec la fonction intégrée classmethod.
@classmethod
def some_class_method(cls, *args, **kwds):
pass
@staticmethod
désactive simplement la fonction par défaut en tant que descripteur de méthode. classmethod encapsule votre fonction dans un conteneur appelable qui passe une référence à la classe propriétaire en premier argument:
>>> class C(object):
... pass
...
>>> def f():
... pass
...
>>> staticmethod(f).__get__(None, C)
<function f at 0x5c1cf0>
>>> classmethod(f).__get__(None, C)
<bound method type.f of <class '__main__.C'>>
En fait, classmethod
a un temps système d’exécution, mais permet d’accéder à la classe propriétaire. Sinon, je vous recommande d'utiliser une métaclasse et de placer les méthodes de classe sur cette métaclasse:
>>> class CMeta(type):
... def foo(cls):
... print cls
...
>>> class C(object):
... __metaclass__ = CMeta
...
>>> C.foo()
<class '__main__.C'>
Le guide définitif sur l'utilisation des méthodes statiques, de classes ou abstraites en Python est un bon lien pour cette rubrique et le résume comme suit.
@staticmethod
fonction n'est rien d'autre qu'une fonction définie dans une classe. Il est appelable sans instancier d'abord la classe. Sa définition est immuable par héritage.
@classmethod
fonction également appelable sans instanciation de la classe, mais sa définition suit la classe Sub, et non la classe Parent, via l'héritage, pouvant être remplacée par la sous-classe . C’est parce que le premier argument de la fonction _@classmethod
_ doit toujours être cls (class).
Permettez-moi de dire la similitude entre une méthode décorée avec @classmethod vs @staticmethod en premier.
Similarité: Les deux peuvent être appelés sur la classe elle-même, plutôt que simplement sur la ) instance de la classe. Donc, dans un sens, les deux méthodes sont les méthodes de Class .
Différence: Une méthode de classe recevra la classe elle-même comme premier argument, contrairement à une méthode statique.
Ainsi, une méthode statique n’est, dans un sens, pas liée à la classe elle-même et reste suspendue simplement parce qu’elle peut avoir une fonctionnalité connexe.
>>> class Klaus:
@classmethod
def classmthd(*args):
return args
@staticmethod
def staticmthd(*args):
return args
# 1. Call classmethod without any arg
>>> Klaus.classmthd()
(__main__.Klaus,) # the class gets passed as the first argument
# 2. Call classmethod with 1 arg
>>> Klaus.classmthd('chumma')
(__main__.Klaus, 'chumma')
# 3. Call staticmethod without any arg
>>> Klaus.staticmthd()
()
# 4. Call staticmethod with 1 arg
>>> Klaus.staticmthd('chumma')
('chumma',)
Un autre élément à prendre en compte, méthode statique vs méthode méthode, est l'héritage. Disons que vous avez la classe suivante:
class Foo(object):
@staticmethod
def bar():
return "In Foo"
Et vous voulez ensuite surcharger bar()
dans une classe enfant:
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
Cela fonctionne, mais notez que maintenant, l'implémentation bar()
dans la classe enfant (Foo2
) ne peut plus tirer parti de quoi que ce soit spécifique à cette classe. Par exemple, supposons que Foo2
dispose d'une méthode appelée magic()
que vous souhaitez utiliser dans l'implémentation Foo2
de bar()
:
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
@staticmethod
def magic():
return "Something useful you'd like to use in bar, but now can't"
La solution consiste à appeler Foo2.magic()
dans bar()
, mais vous vous répétez (si le nom de Foo2
change, vous devez vous rappeler de mettre à jour cette méthode bar()
).
Pour moi, ceci est une légère violation du principe ouvert/fermé , car une décision prise dans Foo
affecte votre capacité à refactoriser le code commun dans une classe dérivée (c'est-à-dire qu'il est moins ouvert aux extension). Si bar()
était un classmethod
, tout irait bien:
class Foo(object):
@classmethod
def bar(cls):
return "In Foo"
class Foo2(Foo):
@classmethod
def bar(cls):
return "In Foo2 " + cls.magic()
@classmethod
def magic(cls):
return "MAGIC"
print Foo2().bar()
Donne: In Foo2 MAGIC
Je vais essayer d'expliquer la différence fondamentale à l'aide d'un exemple.
class A(object):
x = 0
def say_hi(self):
pass
@staticmethod
def say_hi_static():
pass
@classmethod
def say_hi_class(cls):
pass
def run_self(self):
self.x += 1
print self.x # outputs 1
self.say_hi()
self.say_hi_static()
self.say_hi_class()
@staticmethod
def run_static():
print A.x # outputs 0
# A.say_hi() # wrong
A.say_hi_static()
A.say_hi_class()
@classmethod
def run_class(cls):
print cls.x # outputs 0
# cls.say_hi() # wrong
cls.say_hi_static()
cls.say_hi_class()
1 - on peut appeler directement des méthodes statiques et classmethod sans initialiser
# A.run_self() # wrong
A.run_static()
A.run_class()
2- La méthode statique ne peut pas appeler la méthode self mais peut appeler d'autres méthodes statiques et méthodes de classe
3- La méthode statique appartient à la classe et n'utilisera pas d'objet du tout.
4- Les méthodes de classe ne sont pas liées à un objet mais à une classe.
@classmethod: peut être utilisé pour créer un accès global partagé à toutes les instances créées de cette classe ... comme la mise à jour d'un enregistrement par plusieurs utilisateurs .... )
Méthode @static: n'a rien à voir avec la classe ou l'instance associée à ... mais la lisibilité peut utiliser la méthode statique
Le premier argument diffère:
Plus en détail...
Lorsque la méthode d'un objet est appelée, un argument supplémentaire self
lui est automatiquement attribué comme premier argument. C'est la méthode
def f(self, x, y)
doit être appelé avec 2 arguments. self
est automatiquement passé, et c'est l'objet lui-même .
Quand la méthode est décorée
@classmethod
def f(cls, x, y)
l'argument fourni automatiquement n'est pas self
, mais la classe de self
.
Quand la méthode est décorée
@staticmethod
def f(x, y)
la méthode n'est pas donnée aucun argument automatique. Il est uniquement donné les paramètres avec lesquels il est appelé.
classmethod
est principalement utilisé pour les constructeurs alternatifs.staticmethod
n'utilise pas l'état de l'objet. Ce pourrait être une fonction externe à une classe. Il ne met que dans la classe pour regrouper des fonctions ayant des fonctionnalités similaires (par exemple, comme les méthodes statiques de la classe Math
de Java)class Point
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def frompolar(cls, radius, angle):
"""The `cls` argument is the `Point` class itself"""
return cls(radius * cos(angle), radius * sin(angle))
@staticmethod
def angle(x, y):
return atan(y, x)
p1 = Point(3, 2)
p2 = Point.frompolar(3, pi/4)
angle = Point.angle(3, 2)
Vous voudrez peut-être considérer la différence entre:
Class A:
def foo(): # no self parameter, no decorator
pass
et
Class B:
@staticmethod
def foo(): # no self parameter
pass
Cela a changé entre python2 et python3:
python2:
>>> A.foo()
TypeError
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()
python3:
>>> A.foo()
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()
Donc, utiliser @staticmethod
pour des méthodes appelées directement à partir de la classe est devenu facultatif en python3. Si vous souhaitez les appeler à la fois en classe et en instance, vous devez toujours utiliser le décorateur @staticmethod
.
Les autres cas ont été bien couverts par la réponse unutbus.
Ma contribution montre la différence entre @classmethod
, @staticmethod
et les méthodes d'instance, notamment la manière dont une instance peut appeler indirectement un @staticmethod
. Mais au lieu d'appeler indirectement un @staticmethod
à partir d'une instance, le rendre privé peut être plus "Pythonique". Obtenir quelque chose d'une méthode privée n'est pas démontré ici mais c'est fondamentalement le même concept.
#!python3
from os import system
system('cls')
# % % % % % % % % % % % % % % % % % % % %
class DemoClass(object):
# instance methods need a class instance and
# can access the instance through 'self'
def instance_method_1(self):
return 'called from inside the instance_method_1()'
def instance_method_2(self):
# an instance outside the class indirectly calls the static_method
return self.static_method() + ' via instance_method_2()'
# class methods don't need a class instance, they can't access the
# instance (self) but they have access to the class itself via 'cls'
@classmethod
def class_method(cls):
return 'called from inside the class_method()'
# static methods don't have access to 'cls' or 'self', they work like
# regular functions but belong to the class' namespace
@staticmethod
def static_method():
return 'called from inside the static_method()'
# % % % % % % % % % % % % % % % % % % % %
# works even if the class hasn't been instantiated
print(DemoClass.class_method() + '\n')
''' called from inside the class_method() '''
# works even if the class hasn't been instantiated
print(DemoClass.static_method() + '\n')
''' called from inside the static_method() '''
# % % % % % % % % % % % % % % % % % % % %
# >>>>> all methods types can be called on a class instance <<<<<
# instantiate the class
democlassObj = DemoClass()
# call instance_method_1()
print(democlassObj.instance_method_1() + '\n')
''' called from inside the instance_method_1() '''
# # indirectly call static_method through instance_method_2(), there's really no use
# for this since a @staticmethod can be called whether the class has been
# instantiated or not
print(democlassObj.instance_method_2() + '\n')
''' called from inside the static_method() via instance_method_2() '''
# call class_method()
print(democlassObj.class_method() + '\n')
''' called from inside the class_method() '''
# call static_method()
print(democlassObj.static_method())
''' called from inside the static_method() '''
"""
# whether the class is instantiated or not, this doesn't work
print(DemoClass.instance_method_1() + '\n')
'''
TypeError: TypeError: unbound method instancemethod() must be called with
DemoClass instance as first argument (got nothing instead)
'''
"""
Les méthodes de classe, comme leur nom l'indique, sont utilisées pour modifier les classes et non les objets. Pour modifier les classes, ils modifieront les attributs de classe (pas les attributs d'objet), car c'est ainsi que vous mettez à jour les classes. C'est la raison pour laquelle les méthodes de classe prennent la classe (généralement désignée par 'cls') comme premier argument.
class A(object):
m=54
@classmethod
def class_method(cls):
print "m is %d" % cls.m
Les méthodes statiques, d’autre part, sont utilisées pour exécuter des fonctionnalités qui ne sont pas liées à la classe, c’est-à-dire qu’elles ne liront ou n’écriront pas de variables de classe. Par conséquent, les méthodes statiques ne prennent pas les classes comme arguments. Ils sont utilisés pour que les classes puissent exécuter des fonctionnalités qui ne sont pas directement liées à l'objectif de la classe.
class X(object):
m=54 #will not be referenced
@staticmethod
def static_method():
print "Referencing/calling a variable or function outside this class. E.g. Some global variable/function."
Analysez @staticmethod littéralement en fournissant des informations différentes.
Une méthode normale d'une classe est une méthode implicite dynamique qui prend l'instance comme premier argument.
En revanche, une méthode statique ne prend pas l'instance comme premier argument, elle s'appelle donc 'static'.
Une méthode statique est en effet une fonction aussi normale que celle utilisée en dehors d'une définition de classe.
Il est heureusement regroupé dans la classe uniquement pour se rapprocher de l'endroit où il est appliqué ou vous pouvez faire défiler l'écran pour le trouver.