python 7 : La différence entre @staticmethod et @classmethod

in #utopian-io8 years ago

La différence entre @staticmethod et @classmethod en Python

Introduction

this is article is about the methods @staticmethod and @classmethod in Python and the difference between them.

image.png

les méthodes simples, static et les méthodes de class

Les méthodes les plus utilisées dans les classes sont les méthodes d'instance, l'instance est passée comme le premier argument d'une méthode.

Par exemple, une méthode d'instance basique serait comme suivant:

1class alb(object):
2    def __init__(self, info):
3       self.info = info
 
4   def printd(self):
        print(self.info)
 
5 id1 = alb('clin')
6 id2 = alb('voyn')
 
7 id1.printd()
8 id2.printd()

après l'exécution du code , on obtient:

clin
voyn

on peut conclure que :

  • des arguments sont passés à la méthode.
  • l'argument self réfère à l'instance.
  • On a pas besoin de fournir une instance à une méthode, tant que qu"elle est gérée par l'interpréteur lui même.

Supposons maintenant qu'on veut écrire une méthode qui interagit avec des classes et non pas avec les instances? Pour faire cela, on va coder une simple fonction de classe qui va diffuser le code relatif à la classe à l'extérieur de la classe, toutefois cela peut causer un problème de maintenance au niveau du code .

Exemple:

def avoir_no_des_instances(clas_obj):
    return cls_obj.no_instan
 
class alb(object):
    no_instan = 0
 
    def __init__(self):
        alb.no_instan = alb.no_instan + 1
 
id1 = alb()
id2 = alb()
 
print(avoir_no_des_instances(alb))

Ce qui nous donne le résultat suivant:

2

La méthode classmethod()

Ce qu'on veut faire maintenant est de créer une fonction dans une classe qui fera travailler la classe objet au lieu de l'instance. Si on veut avoir le nombre d'instances, tout ce qu'on doit faire est comme suivant:

def avoir_no_des_instances(ins_obj):
    return ins_obj.no_instan
 
class alb(object):
    no_instan = 0
 
    def __init__(self):
    alb.no_instan = alb.no_instan + 1
 
id1 = alb()
id2 = alb()
print avoir_no_des_instances(id1)

2

On peut aussi créer une méthode dans une classe en utilisant @classmethod.

class alb(object):
    no_instan = 0
 
    def __init__(self):
        alb.no_instan = alb.no_instan + 1
 
    @classmethod
    def avoir_no_des_instances(cls_obj):
        return cls_obj.no_instan
 
id1 = alb()
id2 = alb()
 
print id1.avoir_no_des_instances()
print alb.avoir_no_des_instances()

après l'exécution du code:

2
2

L'avantage de cela est: qu'on appelle une méthode d'une instance ou d'une classe, la classe est passée pour le premier argument.

La méthode @staticmethod

Il y'a souvent une fonctionnalité liée à la classe, mais qui a tout de même besoin d'une classe ou d'une instance pour fonctionner. Peut être pour configurer les variables d'environnement ou pour changer un attribut dans une autre classe, etc. Dans des situations pareilles, on peut aussi utiliser une fonction, toutefois, cela peut engendrer ultérieurement des problèmes de maintenance au niveau du code.

Voici un cas simple:

IND = 'ON'
 
def checkind():
    return (IND == 'ON')
 
class alb(object):
     def __init__(self,info):
        self.info = info
 
def do_reset(self):
    if checkind():
        print('Reset done for:', self.info)
 
def set_db(self):
    if checkind():
        self.db = 'new db connection'
        print('DB connection made for:',self.info)
 
id1 = alb(17)
id1.do_reset()
id1.set_db()

le résultat de l'exécution est:

Reset done for: 17
DB connection made for: 17

Si on utilise la méthode @staticmethod , le code précédent devient:

IND = 'ON'
 
class alb(object):
    def __init__(self, info):
        self.info = info
 
    @staticmethod
    def checkind():
        return (IND == 'ON')
 
    def do_reset(self):
        if self.checkind():
            print('Reset done for:', self.info)
 
    def set_db(self):
        if self.checkind():
            self.db = 'New db connection'
        print('DB connection made for: ', self.info)
 
id1 = Kls(17)
id1.do_reset()
id1.set_db()

Ce qui nous donnera le même résultat

La méthode @staticmethod est différente à la méthode @classmethod

class alb(object):
    def __init__(self, info):
        self.info = info
 
    def printd(self):
        print(self.info)
 
    @staticmethod
        def static_method(*arg):
            print('static:', arg)
 
    @classmethod
        def class_method(*arg):
            print('classe:', arg)

>>> ide = alb(23)
>>> ide.printd()
23
>>> ide.static_method()
Static: ()
>>> ide.class_method()
Class: (<class '__main__.alb'>,)
>>> alb.printd()
TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead)
>>> alb.static_method()
Static: ()
>>> alb.class_method()
Class: (<class '__main__.alb'>,)



Posted on Utopian.io - Rewarding Open Source Contributors

Sort:  

Thank you for the contribution. It has been approved.

You can contact us on Discord.
[utopian-moderator]

Hey @raptorjesus I am @utopian-io. I have just upvoted you!

Achievements

  • You have less than 500 followers. Just gave you a gift to help you succeed!
  • Seems like you contribute quite often. AMAZING!

Suggestions

  • Contribute more often to get higher and higher rewards. I wish to see you often!
  • Work on your followers to increase the votes/rewards. I follow what humans do and my vote is mainly based on that. Good luck!

Get Noticed!

  • Did you know project owners can manually vote with their own voting power or by voting power delegated to their projects? Ask the project owner to review your contributions!

Community-Driven Witness!

I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!

mooncryption-utopian-witness-gif

Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x

Coin Marketplace

STEEM 0.04
TRX 0.32
JST 0.078
BTC 65594.32
ETH 1720.32
USDT 1.00
SBD 0.42