60 votes

Méthodes portant le même nom dans une même classe en Python

Comment puis-je déclarer plusieurs méthodes portant le même nom, mais avec des nombres de paramètres différents ou des types différents dans une même classe ?

Que dois-je changer dans la classe suivante ?

class MyClass:
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
    def my_method(self,parameter_A_that_Must_Be_String):
        print parameter_A_that_Must_Be_String

    def my_method(self,parameter_A_that_Must_Be_String,parameter_B_that_Must_Be_String):
        print parameter_A_that_Must_Be_String
        print parameter_B_that_Must_Be_String

    def my_method(self,parameter_A_that_Must_Be_String,parameter_A_that_Must_Be_Int):
        print parameter_A_that_Must_Be_String * parameter_A_that_Must_Be_Int

75voto

kefeizhou Points 1917

Vous pouvez avoir une fonction qui prend un nombre variable d'arguments.

def my_method(*args, **kwds):
    # Do something

# When you call the method
my_method(a1, a2, k1=a3, k2=a4)

# You get:
args = (a1, a2)
kwds = {'k1':a3, 'k2':a4}

Vous pouvez donc modifier votre fonction comme suit :

def my_method(*args):
    if len(args) == 1 and isinstance(args[0], str):
        # Case 1
    elif len(args) == 2 and isinstance(args[1], int):
        # Case 2
    elif len(args) == 2 and isinstance(args[1], str):
        # Case 3

32voto

Tu ne peux pas. Il n'y a pas de surcharges, de multiméthodes ou de choses similaires. Un nom fait référence à une seule chose. De toute façon, en ce qui concerne le langage, vous pouvez toujours les émuler vous-même... Vous podría les types de contrôle avec isinstance (mais faites-le correctement - par exemple, en Python 2, utilisez basestring pour détecter à la fois les chaînes de caractères et l'unicode), mais c'est laid, généralement déconseillé et rarement utile. Si les méthodes font des choses différentes, donnez-leur des noms différents. Pensez également au polymorphisme.

13voto

Mark McDonald Points 2503

En utilisant Python 3.5 ou plus, vous pouvez utiliser @typing.overload pour fournir des annotations de type pour les fonctions/méthodes surchargées.

Extrait de la documentation :

@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    <actual implementation>

6voto

SteveMc Points 809

Réponse courte : vous ne pouvez pas ( voir cette discussion précédente ). Typiquement, vous utiliseriez quelque chose comme (vous pourriez ajouter plus de vérification de type et réordonner) :

def my_method(self,parameter_A, parameter_B=None):
  if isinstance(parameter_B, int):
    print parameter_A * parameter_B
  else:
    print parameter_A
    if parameter_B is not None:
      print parameter_B

2voto

gruszczy Points 14097

Vous pouvez essayer les multiméthodes en Python :

http://www.artima.com/weblogs/viewpost.jsp?thread=101605

Mais je ne crois pas que la multiméthode soit une voie à suivre. Les objets que vous passez à une méthode devraient plutôt avoir une interface commune. Vous essayez d'obtenir une surcharge de méthodes similaire à celle du C++, mais elle est très rarement requise en Python. Une façon de le faire est une cascade de ifs en utilisant isinstance mais c'est moche.

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