web-dev-qa-db-fra.com

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

class MyClass:
    def myFunc(self):
        pass

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

43
user975135

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

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

class MyClass:
    myMethod = func

Vous pouvez également ajouter une fonction à une classe après sa définition:

class MyClass:
    pass

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

MyClass.myMethod = func

Vous pouvez définir la fonction et la classe dans différents modules 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 dynamiquement (comme dans mon deuxième exemple), car alors vous '' d ont un comportement étonnamment différent de la classe selon qu'un autre module a été importé ou non.

Je voudrais souligner que bien que cela soit possible en Python, c'est un peu inhabituel. Vous mentionnez dans un commentaire que les méthodes "les utilisateurs sont autorisés à en ajouter". 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 changer directement la vôtre.

72
Weeble

Je ne sais pas si cela est utile, mais cela m'a rendu un peu plus clair. Bien que je ne sois pas sûr que ce soit une bonne pratique de le faire de cette façon ...

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

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

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

Voyons d'abord ce qui se passe dans MyClass1. foobar dans cette classe est similaire à une méthode normale comme si elle était définie dans la définition de classe (c'est-à-dire qu'il s'agit d'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 updog"

En quoi cela diffère-t-il de MyClass2? Dans 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 transmettre 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 updog"

Espérons que cela soit aussi clair que de la boue ...

6
ewellinger

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)
1
Matt Alcock

Je donne un aperçu de ce que vous recherchez, 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 __== '__main__':
    obj = MyClass()

Cela imprimera

>>> 2
0
aweis