web-dev-qa-db-fra.com

python - devrais-je utiliser des méthodes statiques ou des fonctions de niveau supérieur

Je viens de Java et je suis novice en python. J'ai quelques scripts qui partagent certaines fonctions d'assistance uniques à l'application liées à la lecture et à l'écriture de fichiers. Certaines fonctions associées à la lecture, d'autres à l'écriture. En cherchant la bonne approche, j'ai vu ceci: Méthodes statiques en Python?

Il mentionne dans sa réponse: 

Enfin, utilisez la méthode statique avec parcimonie! Il existe très peu de situations dans lesquelles les méthodes statiques sont nécessaires en Python, et je les ai souvent vues utilisées pour lesquelles une fonction "de niveau supérieur" distincte aurait été plus claire.

Je ne comprends pas très bien les fonctions de haut niveau et je ne suis pas sûr de donner cet exemple simple, qui est meilleur: 1) créer une classe pour un lecteur avec des fonctions de lecteur statique et la même chose pour un écrivain ou 2) pour déclarer ces aides en tant que fonctions globales et pourquoi? 

EDIT:VRAIMENTbon article sur ce sujet que je viens de trouver http://tomayko.com/writings/the-static-method-thing

34
Brad

En Java, il existe l’idée (erronée) d’utiliser des classes partout, même simplement de regrouper des fonctions statiques qui ne partagent aucun état (et donc ces classes ne seront jamais instanciées).

Python demande ici de différer; si vous avez des fonctions qui n'ont pas un état partagé1 (et donc, en Java, il s'agirait généralement de static fonctions) et ne sont pas étroitement liés à une classe "réelle" (= une qui est réellement instanciée). Vous utilisez simplement des fonctions libres dans un module.

Le raisonnement derrière ceci est qu'une classe n'est nécessaire que lorsque vous voulez réellement l'instancier, ce qui fait qu'il est inutile d'avoir une classe comme conteneur pour plusieurs fonctions qui n'ont pas besoin de partager un état spécifique à une instance.

En fait, vous pouvez un peu penser d’un module comme d’une classe static - c’est-à-dire un conteneur de fonctions (= méthodes statiques), de variables de module (= champs statiques) et de types.

Le bon côté de Python est qu’avoir une fonction de niveau supérieur ne pose pas de problèmes de pollution globale des espaces de noms, car en Python, les fonctions/objets/... sont toujours au niveau du module. Ainsi, vous pouvez toujours grouper des fonctions par module, sans la taxe class- inutile.


  1. en fait, ils peuvent ont un certain état partagé, sous la forme de variables de niveau module (donc, singletons); encore une fois, l'analogie modules-classes statiques semble tenir.
39
Matteo Italia

Du zen de Python (import this):

Namespaces are one honking great idea -- let's do more of those!

L'une des principales raisons de créer des méthodes statiques dans un langage tel que Java est de s'assurer que ces méthodes ne finissent pas par polluer l'espace de noms global. (Bien que Java applique ses propres conventions relatives aux espaces de noms en interdisant totalement les fonctions "au niveau du paquet"!) En Python, toutes les fonctions "de niveau supérieur" sont automatiquement placées dans l'espace de noms du module contenant ces fonctions, il n'y a donc aucun risque de espace de noms de cette façon.

En d'autres termes, comme beaucoup d'autres langages, Python peut créer des espaces de noms de différentes manières. Dans ce cas, il est inutile de créer une classe contenant uniquement des méthodes statiques, lorsqu'un module remplit la même fonction d'espacement de noms sans le fouillis (ou la charge cognitive) associé à la définition d'une classe.

9
lmjohns3

C'est une question de pollution de l'espace de noms. Si vous avez un module avec plusieurs classes et des fonctions qui n'ont de sens que pour une classe et ses descendants, faites-en une méthode statique. La méthode statique peut être appelée en utilisant le nom de la classe ou en utilisant un objet de la classe.

>>> class A(object):
...     @staticmethod
...     def static_1():
...             print 'i am static'
...     def a(self):
...             self.static_1()
...
>>> A.static_1()
i am static
>>> a=A()
>>> a.a()
i am static
>>> a.static_1()
i am static
>>> class B(A):
...     pass
...
>>> b=B()
>>> b.static_1()
i am static
>>>
4
tdelaney

Si la fonction est liée à une classe, faites-en une méthode statique. Par exemple:

class DBobject():
    name = StringProperty()

    @staticmethod
    def get_by_name(name):
        return db.select('select * from DBobject where name = "%s"' % name)

python = DBobject.get_by_name('python')

Autrement dit, la méthode est complètement liée à la classe DBobject et doit donc être une méthode statique.

4
Brent Washburne

Un autre aspect des méthodes statiques Python est que lorsqu'elles sont appelées sur des instances, elles sont polymorphes sur le type de la variable sur laquelle elles sont appelées, bien qu'elles ne possèdent pas d'instance de self.

Par exemple:

class BaseClass:
    @staticmethod
    def my_method():
        return 0


class SubclassLeft:
    @staticmethod
    def my_method():
        return "left"


class SubclassRight:
    @staticmethod
    def my_method():
        return "right"


instances = [BaseClass(), SubclassLeft(), SubclassRight()]

for i in instances:
    print(i.my_method())

En cours d'exécution, il en résulte

$ python example.py
0
left
right
0
andyg0808