Méthodes statiques - Comment appeler une méthode à partir d'une autre méthode?

96

Quand j'ai des méthodes régulières pour appeler une autre méthode dans une classe, je dois le faire

class test:
    def __init__(self):
        pass
    def dosomething(self):
        print "do something"
        self.dosomethingelse()
    def dosomethingelse(self):
        print "do something else"

mais quand j'ai des méthodes statiques je ne peux pas écrire

self.dosomethingelse()

car il n'y a pas d'instance. Comment dois-je faire en Python pour appeler une méthode statique à partir d'une autre méthode statique de la même classe?

Edit: quel bordel. Ok, j'ai modifié la question à la question d'origine. J'ai déjà la réponse à la deuxième question qui se trouve dans le commentaire de Peter Hansen. Si vous pensez que je devrais ouvrir une autre question pour une réponse que j'ai déjà, veuillez me le dire.

Pablo
la source
3
@pablo: vous ne pouvez pas changer l'essence de la question !! Terminez cette question et commencez-en une autre !!
jldupont
OK OK. voulez-vous dire supprimer la question? La réponse est déjà là dans le commentaire de Peter Hansen
Pablo
@pablo: vous ne pouvez pas supprimer ici ce qui ne serait pas poli pour tous ceux qui ont répondu à votre question. Vous devez accepter une réponse et créer une nouvelle question.
jldupont
1
@pablo: et juste pour être clair: une réponse doit être acceptée pour la formulation de votre question initiale . Ne vous inquiétez pas, vous apprendrez votre chemin ici. Cheers :-)
jldupont

Réponses:

79

class.method devrait marcher.

class SomeClass:
  @classmethod
  def some_class_method(cls):
    pass

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()
jldupont
la source
17
Un conseil devrait être ajouté ici: il est clair que les méthodes de classe n'ont aucun inconvénient par rapport aux méthodes statiques, et les méthodes de classe permettent à la méthode d'être étendue à l'avenir pour appeler d'autres méthodes de classe. Ainsi, il devrait toujours être préféré, même s'il n'y a pas de besoin immédiat.
u0b34a0f6ae
1
@ u0b34a0f6ae: Je ne sais pas si je fais quelque chose de bien ou pas ... mais j'ai défini un décorateur dans une classe. Le décorateur devait être une «méthode statique», pas une «méthode de classe».
André Caldas
@ u0b34a0f6ae Les méthodes de classe sont-elles toujours thread-safe? Dans mon cas d'utilisation, j'utilise des méthodes statiques dans les threads pour empêcher l'accès accidentel à la classe qui peut ne pas être thread-safe.
aquavitae
@ u0b34a0f6ae est toujours un peu fort. Par exemple, l'utilisation des méthodes statiques PySpark peut être utilisée dans les travaux rdd et les méthodes de classe ne le peuvent pas.
Laurens Koppenol
135

Comment dois-je faire en Python pour appeler une méthode statique à partir d'une autre méthode statique de la même classe?

class Test() :
    @staticmethod
    def static_method_to_call()
        pass

    @staticmethod
    def another_static_method() :
        Test.static_method_to_call()

    @classmethod
    def another_class_method(cls) :
        cls.static_method_to_call()
warvariuc
la source
L'appel Test.static_method_to_call()devrait également fonctionner à partir d'autres méthodes non statiques et non-classe de cette classe, non? (... et probablement d'autres classes aussi?)
gr4nt3d
Oui, Test.static_method_to_call()fonctionnera de n'importe où.
warvariuc
11

REMARQUE - il semble que la question en ait changé. La réponse à la question de savoir comment vous appelez une méthode d'instance à partir d'une méthode statique est que vous ne pouvez pas sans passer une instance en tant qu'argument ou instancier cette instance dans la méthode statique.

Ce qui suit est principalement de répondre "comment appeler une méthode statique à partir d'une autre méthode statique":

Gardez à l' esprit qu'il y a une différence entre les méthodes de statiques et les méthodes de classe en Python. Une méthode statique ne prend pas de premier argument implicite, tandis qu'une méthode de classe prend la classe comme premier argument implicite (généralement clspar convention). Dans cet esprit, voici comment procéder:

S'il s'agit d'une méthode statique:

test.dosomethingelse()

Si c'est une méthode de classe:

cls.dosomethingelse()
Jason Baker
la source
1
vous ne pouvez utiliser que cls.dosomethingelse()dans la définition de classe.
jldupont
3
Pour être plus précis, vous ne pouvez utiliser que cls.dosomethingelse()depuis la méthode de classe elle-même. Tout comme vous ne pouvez utiliser qu'à selfpartir d'une méthode d'instance elle-même.
Jason Baker
1
désolé, j'ai mal écrit la question. OUPS!. Je voulais écrire "Comment dois-je faire en Python pour appeler une méthode d'instance à partir d'une autre méthode statique de la même classe" et non "Comment dois-je faire en Python pour appeler une méthode statique à partir d'une autre méthode statique du même class "
Pablo
@pablo: Dans ce cas, vous devez écrire une autre question et terminer celle-ci.
jldupont
@jldupont, j'ai déjà la réponse mais en un seul commentaire. Que dois-je faire parce que je ne peux pas l'accepter, mais ce serait un gaspillage d'effacer la question, n'est-ce pas?
Pablo
4

OK, la principale différence entre les méthodes de classe et les méthodes statiques est:

  • La méthode de classe a sa propre identité, c'est pourquoi elles doivent être appelées depuis une INSTANCE.
  • d'autre part, la méthode statique peut être partagée entre plusieurs instances de sorte qu'elle doit être appelée depuis THE CLASS
Ahmad Dwaik
la source
0

vous ne pouvez pas appeler des méthodes non statiques à partir de méthodes statiques mais en créant une instance à l'intérieur de la méthode statique ... cela devrait fonctionner comme ça

class test2(object):
    def __init__(self):
        pass

    @staticmethod
    def dosomething():
        print "do something"
        #creating an instance to be able to call dosomethingelse(),or you may use any existing instace
        a=test2()
        a.dosomethingelse()

    def dosomethingelse(self):
        print "do something else"

test2.dosomething()

j'espère que cela vous aidera :)

Ahmad Dwaik
la source
3
IMO, cette approche est nettement pire que d'utiliser simplement @classmethodpour déclarer vos méthodes, et d'utiliser cls.dosomethingelse()dedans cls.dosomething()- pire en termes de performances (instanciation d'objets juste pour accéder à une méthode statique) et de lisibilité (ce n'est pas simple, et j'imagine si ce genre du modèle est devenu passe-partout, toute la base de code pourrait devenir assez difficile à analyser pour un simple humain)
Kyle Wild
Comme je l'ai lu ailleurs chez SO, au lieu d'initialiser l'instance directement pour appeler une méthode, vous pouvez simplement l'appeler - elle s'initialisera d'elle-même.
Nakilon
0

Si ceux-ci ne dépendent pas de la classe ou de l'instance, pourquoi ne pas en faire une fonction? Comme cela semble être la solution évidente. À moins bien sûr que vous ne pensiez que cela devra être écrasé, sous-classe, etc. Si tel est le cas, les réponses précédentes sont le meilleur choix. Croisons les doigts, je ne serai pas marqué pour simplement offrir une solution alternative qui peut ou non répondre aux besoins de quelqu'un;).

Comme la bonne réponse dépendra du cas d'utilisation du code en question;)

AppHandwerker
la source