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)
4 Réponses :
Parfois, les gens python aiment dire "Il vaut mieux demander le pardon que l'autorisation" ... Mais je dis que c'est juste une question de préférence. Vous pouvez également utiliser isinstance code> tout aussi facilement si vous savez que vous allez seulement obtenir des chaînes, ou
utilisateur code>. P> p>
J'utiliserais isinstance code>, mais cela fonctionne également:
Utiliser isinstance code> est une bonne approche ... Il y a une autre approche pour cette solution
Une solution comme Mgilson, mais légèrement différente: pourquoi? Parce que cette façon, Il pourrait être non pertinent, mais je préfère concentrer la manipulation des exceptions à ces endroits vraiment inété de les avoir. p> p> attributeError code> s dans
retirez () code> ne sont pas supprimés. P>
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) code> serait aussi un moyen d'aller ...
et +1 pour déterminer comment faire cela dans une doublure 1 (en utilisant getattr code>) - 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.) ...
Oui,
isinstance code> 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) code> 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!