8
votes

Comment puis-je extraire un sous-ensemble d'énumération python sans le redéfinir?

Comment puis-je extraire un sous-ensemble d'énumération python sans le redéfinir?

@unique
class MyTrySubset(Enum):
    pass

for item in MyEnum:
    setattr(MyTrySubset, item.name, item.value)

Je voudrais obtenir un équivalent à MyDesiredSubset sans avoir à le redéfinir.

@unique
class MyDesiredSubset(Enum):
    THREE = 3
    FOUR = 4

Jusqu'à présent, j'ai essayé quelque chose comme ça, mais MyTrySubset est cassé et le code est moche.

from enum import unique, Enum
@unique
class MyEnum(Enum):
    ONE = 1
    TWO = 2
    THREE = 3
    FOUR = 4

Des suggestions pour obtenir MyDesiredSubset sans le redéfinir?


0 commentaires

3 Réponses :


3
votes

Votre code ne fonctionnera pas - les énumérations ne sont pas tout à fait des classes:

@unique
class MyIntEnum(IntEnum):
    ONE = 1
    TWO = 2
    THREE = 3
    FOUR = 4

@unique
class MyDesiredIntSubset(IntEnum):
    THREE = MyIntEnum.THREE
    FOUR = MyIntEnum.FOUR

print(MyDesiredSubset.THREE == MyEnum.THREE)       # False
print(MyDesiredIntSubset.THREE == MyIntEnum.THREE) # True 
print(MyDesiredIntSubset.THREE == 3)               # True @Steven Rumbalski
MyOther = Enum("MyOther", [(a.name,a.value) for a in MyEnum 
                           if a in [MyEnum.THREE,MyEnum.FOUR]] )

Utilisez l'autre énumération pour déclarer celle-ci (ne sera pas comparable cependant):

@unique
class MyDesiredSubset(Enum):
    THREE = MyEnum.THREE
    FOUR = MyEnum.FOUR

ou utilisez l'approche fluide:

 for item in MyEnum: 
    setattr(MyTrySubset, item.name,     item.value)  # no duplication error by @unique
    setattr(MyTrySubset, item.name+"a", item.value)  # no duplication error by @unique

for s in MyTrySubset:
    print(s)           # no output - at all

for s in MyEnum:
    print(s)           # prints all repr() of all Enum-values defined

Si vous utilisez IntEnum à la place, vous pouvez même les comparer:

@unique
class MyEnum(Enum):
    ONE = 1
    TWO = 2
    THREE = 3
    FOUR = 4

@unique
class MyTrySubset(Enum):
    pass


2 commentaires

Je suppose qu'il convient de noter que print (MyDesiredIntSubset.THREE == 3) # True .


Cette réponse bien plus que ce que je recherchais, mais l'approche fluide fonctionne très bien.



2
votes

La réponse de Patrick Artner contient ce que je cherchais en boucle dans une énumération avec une instruction if conservant les éléments souhaités.

Je viens d'extraire les bits pertinents.

class MySubset(Enum):
    THREE = 3
    FOUR = 4

Semble être équivalent à (sans le décorateur unique):

MySubset = Enum("MySubet", [(a.name, a.value) for a in MyEnum if a.value > 2 ] )


0 commentaires

2
votes

Je suggérerais de définir les propriétés comme indiqué dans cette question :

MyEnum.my_desired_subset

Et maintenant vous pouvez faire:

from enum import unique, Enum
@unique
class MyEnum(Enum):
    ONE = 1
    TWO = 2
    THREE = 3
    FOUR = 4

    @property
    def my_desired_subset(self):
        return self.THREE, self.FOUR

    @property
    def is_desired_subset(self):
        return self in self.my_desired_subset


0 commentaires