78 votes

Définir une méthode en dehors de la définition de la classe ?

class MyClass:
    def myFunc(self):
        pass

Puis-je créer MyFunc() en dehors de la définition de la classe, peut-être même dans un autre module ?

116voto

Weeble Points 6248

Oui. Vous pouvez définir une fonction en dehors d'une classe et l'utiliser ensuite dans le corps de la classe comme une méthode :

def func(self):
    print("func")

class MyClass:
    myMethod = func

Vous pouvez également ajouter une fonction à une classe après qu'elle ait été définie :

class MyClass:
    pass

def func(self):
    print("func")

MyClass.myMethod = func

Vous pouvez définir la fonction et la classe dans des modules différents si vous le souhaitez, mais je vous déconseille de définir la classe dans un module, puis de l'importer dans un autre et de lui ajouter des méthodes de manière dynamique (comme dans mon deuxième exemple), car vous obtiendriez alors un comportement étonnamment différent de la classe selon qu'un autre module a été importé ou non.

Je tiens à préciser que si cela est possible en Python, c'est un peu inhabituel. Vous mentionnez dans un commentaire que "les utilisateurs sont autorisés à ajouter d'autres" méthodes. Cela semble étrange. Si vous écrivez une bibliothèque, vous ne voulez probablement pas que les utilisateurs de la bibliothèque ajoutent dynamiquement des méthodes aux classes de la bibliothèque. Il est plus normal pour les utilisateurs d'une bibliothèque de créer leur propre sous-classe qui hérite de votre classe que de modifier la vôtre directement.

J'ajouterais également un rappel que les fonctions n'ont pas à être dans les classes du tout. Python n'est pas comme Java ou C# et vous pouvez avoir des fonctions qui ne font pas partie d'une classe. Si vous voulez regrouper des fonctions, vous pouvez simplement les mettre dans le même module, et vous pouvez imbriquer des modules dans des paquets. N'utilisez les classes que lorsque vous avez besoin de créer un nouveau type de données, et pas seulement pour regrouper des fonctions.

9voto

ewellinger Points 141

Vous pouvez définir une fonction en dehors d'une classe et l'ajouter ensuite. Cependant, il existe une différence subtile dans l'affectation de la fonction à la classe ou à l'objet d'instance. Voici un exemple :

class MyClass1(object):
    def __init__(self, bar):
        self.foo = 'up'
        MyClass1.foobar = bar

class MyClass2(object):
    def __init__(self, bar):
        self.foo = 'up'
        self.foobar = bar

def bar(self):
    return "What's " + self.foo

Regardons d'abord ce qui se passe dans MyClass1 . foobar dans cette classe est similaire à une méthode normale comme si elle était définie à l'intérieur de la définition de la classe (c'est-à-dire que c'est une méthode liée à l'instance de cette classe). Voyons à quoi cela ressemble...

In [2]: x = MyClass1(bar)

In [3]: x.foobar
Out[3]: <bound method MyClass1.bar of <__main__.MyClass1 object at 0x104346990>>

In [4]: x.foobar()
Out[4]: "What's up"

En quoi cela diffère-t-il de MyClass2 ? Sur MyClass2 , foobar est simplement une référence à la fonction bar et n'est PAS une méthode liée. Pour cette raison, nous devons passer l'instance pour que cette fonction fonctionne correctement, par exemple

In [5]: y = MyClass2(bar)

In [6]: y.foobar
Out[6]: <function __main__.bar>

In [7]: y.foobar()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-6feb04878e5f> in <module>()
----> 1 y.foobar()

TypeError: bar() takes exactly 1 argument (0 given)

In [8]: y.foobar(y)
Out[8]: "What's up"

Bien que je ne sois pas sûr que ce soit une bonne pratique de le faire de cette façon...

5voto

Matt Alcock Points 1913

Oui, vous pouvez certainement avoir des fonctions en dehors d'une classe. Voici un mini exemple...

def date_parse(date_string):
  return date(date_string)

class MyClass:
   def myFunc(self):
       pass

   def myDateFunc(self, date_string):
      self.date = date_parse(date_string)

3voto

aweis Points 1849

Je donne un coup de feu à ce que vous cherchez, où une classe Helper fournit des fonctions à une classe spécialisée ( MyClass )

class Helper(object):

    def add(self, a, b):
        return a + b

    def mul(self, a, b):
        return a * b

class MyClass(Helper):

    def __init__(self):
        Helper.__init__(self)
        print self.add(1, 1)

if __name__ == '__main__':
    obj = MyClass()

Ceci imprimera

>>> 2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X