Comment comparer les Enums en Python?
Depuis Python 3.4, la Enum
classe existe.
Je suis en train d'écrire un programme, où certaines constantes ont un ordre précis et je me demande qui est le plus pythonic de comparer:
class Information(Enum):
ValueOnly = 0
FirstDerivative = 1
SecondDerivative = 2
Maintenant, il y a une méthode, qui doit comparer un information
de Information
avec les différentes énumérations:
information = Information.FirstDerivative
print(value)
if information >= Information.FirstDerivative:
print(jacobian)
if information >= Information.SecondDerivative:
print(hessian)
La comparaison directe ne fonctionne pas avec les Énumérations, il y a donc trois approches et je me demande qui est préférée:
Approche 1: Utiliser les valeurs:
if information.value >= Information.FirstDerivative.value:
...
Approche 2: Utilisation De IntEnum:
class Information(IntEnum):
...
Approche 3: ne Pas utiliser les Énumérations à tous:
class Information:
ValueOnly = 0
FirstDerivative = 1
SecondDerivative = 2
Chaque approche fonctionne, l'Approche de la 1 est un peu plus verbeux, alors que l'Approche 2 utilise pas recommandé IntEnum de classe, tandis que l'Approche et 3 semble être la façon dont on fait cela avant Enum a été ajouté.
J'ai tendance à utiliser la méthode 1, mais je ne suis pas sûr.
Merci pour tout conseil!
Bien sûr, à partir de la documentation: “Pour la majorité des nouveaux code, Enum et le Drapeau sont fortement recommandés, car IntEnum et IntFlag briser certains sémantique des promesses d'une énumération (par le fait d'être comparables à des entiers, et donc par transitivité à d'autres sans rapport avec les énumérations). IntEnum et IntFlag doit être utilisé uniquement dans les cas où Enum et le Drapeau ne le fera pas; par exemple, lorsque les constantes entières sont remplacés par les énumérations, ou pour l'interopérabilité avec d'autres systèmes.”
OriginalL'auteur Sebastian Werk | 2016-09-01
Vous devez vous connecter pour publier un commentaire.
Je n'avais r'rencontré Enum avant, donc j'ai scanné la doc (https://docs.python.org/3/library/enum.html) ... et trouvé OrderedEnum (section 8.13.13.2) N'est-ce pas ce que vous voulez? À partir de la doc:
OriginalL'auteur nigel222
Vous devriez toujours mettre en œuvre les riches comparaison operaters si vous voulez les utiliser avec un
Enum
. À l'aide de lafunctools.total_ordering
classe décorateur, vous avez seulement besoin de mettre en œuvre un__eq__
méthode avec une seule commande, par exemple__lt__
. Depuisenum.Enum
implémente déjà__eq__
cela devient encore plus facile:Terrible, horrible, horrible de choses peuvent se produire avec
IntEnum
. Il a surtout été inclus pour la compatibilité descendante de souci, les énumérations, utilisé pour être mis en œuvre par le sous-classementint
. À partir de la docs:Voici un exemple de pourquoi vous ne voulez pas le faire:
return NotImplemented
au lieu deraise NotImplemented
. Est-il une règle générale, lors de l'utilisation de retour et quand l'augmenter?Eh bien, vous ne pouvez pas
raise NotImplemented
car il n'est pas une exception. Il s'agit d'un singleton. Voir le docs, il est là pour le cas particulier de la riche-les opérateurs de comparaison. LeNotImplementedError
, selon le docs, est là pour quand "méthodes abstraites devrait soulever cette exception lorsqu'elles ont besoin de classes dérivées pour remplacer la méthode. ".Voir également cette question: stackoverflow.com/questions/878943/...
Excellente réponse, bon Monsieur. Cette approche est un succincte – quoique moins efficace – alternative à la
OrderedEnum
classe détaillée dans le officiel de la documentation Python. Alors que leOrderedEnum
solution manuelle de la mise en œuvre de tous les opérateurs de comparaison est modestement plus rapide, le@total_ordering
solution donnée ci-dessus a ses mérites. La concision est une tâche ingrate de la vertu. Par ailleurs, personne ne sait pourquoiOrderedEnum
était simplement documenté plutôt que sur l'ajout de laenum
module?OriginalL'auteur juanpa.arrivillaga