6
votes

Polymorphisme de fonction en python

Je regarde autour de la meilleure façon de le faire, mais je n'ai rien trouvé vraiment convaincu.

J'écris un système où vous avez des objets utilisateur et une collection qui gère ces utilisateurs. Chaque utilisateur a un nom et je souhaite spécifier une fonction dans le gestionnaire capable de prendre le nom de l'utilisateur ou de l'objet utilisateur lui-même. p>

class UserManager: 
  def remove_user(self,user_or_username):
    #If user_or_username is a string
    remote.remove(user_or_username)
    #If user_or_username is a User object
    remote.remove(user_or_username.name)


3 commentaires

Oui, isinstance devrait être correct.


Le polymorphisme n'affecte vraiment que si vous ne savez pas au point d'appeler si vous avez un nom ou un objet utilisateur. Surtout ce n'est pas le cas. Vous devez résister à la tentation de surcharger des fonctions à moins que vous n'ayez vraiment besoin. Ici, vous avez une méthode lorsqu'elle est donnée une chaîne juste des chaînes à une autre méthode. C'est une odeur de code: vous devriez simplement appeler directement l'autre méthode; Lorsque vous avez un appel nom d'utilisateur manager.remove (nom d'utilisateur) directement.


Votre point est valide @Duncan mais dans ce cas, le gestionnaire est une couche intermédiaire et son travail consiste à apporter les appels appropriés à l'utilisateur de mon application. Je voulais explorer cette option pour savoir combien de flexibilité que j'ai eu à ma disposition!


4 Réponses :


2
votes

Parfois, les gens python aiment dire "Il vaut mieux demander le pardon que l'autorisation" ... XXX

Mais je dis que c'est juste une question de préférence. Vous pouvez également utiliser isinstance tout aussi facilement si vous savez que vous allez seulement obtenir des chaînes, ou utilisateur .


0 commentaires

2
votes

J'utiliserais isinstance , mais cela fonctionne également: xxx


0 commentaires

3
votes

Utiliser isinstance est une bonne approche ... Il y a une autre approche pour cette solution xxx


0 commentaires

5
votes

Une solution comme Mgilson, mais légèrement différente: xxx

pourquoi? Parce que cette façon, attributeError s dans retirez () ne sont pas supprimés.

Il pourrait être non pertinent, mais je préfère concentrer la manipulation des exceptions à ces endroits vraiment inété de les avoir.


4 commentaires

Pour une factorisation encore meilleure, vous pourriez envisager d'extraire une fonction pour l'essai / à l'exception du bloc. Cela pourrait être utile ailleurs aussi.


@Karlknechtel Eh bien, un Nom d'utilisateur = getattr (user_or_username, "nom", user_or_username) serait aussi un moyen d'aller ...


et +1 pour déterminer comment faire cela dans une doublure 1 (en utilisant getattr ) - pas que je ne perférite généralement 1-liners ...


@LLGLGLG a accepté - bien que j'ai tendance à penser que lbyl vs. EAFP dépend de la demande (et des préférences de programmeur / de l'arrière-plan dans d'autres langues, etc.) ...