Python enum not working properly

I found very strange behavior in the Enum class in Python. So the numbered type is simple:

from enum import Enum Analysis = Enum('Analysis', 'static dynamic') 

So, I use this enumerated type for objects with a step to store it in attribute analysis as follows:

 class Step: def __init__(self): self.analysis = None self.bcs = [] 

It’s very simple so far, so when I have several of these steps in the list, I try to look at the enumerated type and it has been assigned correctly. But they are not equal:

 # loop over steps for s, step in enumerate(kwargs['steps']): print(kwargs) print(step) print(step.analysis) print("test for equality: ",(step.analysis == Analysis.static)) quit() 

which prints

 {'mesh': <fem.mesh.mesh.Mesh object at 0x10614d438>, 'steps': [<hybrida.fem.step.Step object at 0x10614d278>, <hybrida.fem.step.Step object at 0x10616a710>, <hybrida.fem.step.Step object at 0x10616a390>]} Step: analysis: Analysis.static bcs: [<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a0f0>, <hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a320>, <hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a3c8>, <hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a470>, <hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a518>, <hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a5c0>, <hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a668>] Analysis.static test for equality: False 

This is not true, but I have no idea how to debug this.

UPDATE

Following @martineau's suggestion, I created instead of IntEnum and solved my problem. However, I do not understand why the normal Enum does not work.

+6
source share
1 answer

In the comments you say:

The input file contains many steps and every time I add a new step I need to configure the type of analysis

If you understand correctly, you say that every time you add a new step, you create a new Enum object. Perhaps that is why you see your “mistake”. The values ​​of two different Enum objects, despite the same name and order, are not necessarily compared as equal. For instance:

 import enum Analysis1 = enum.Enum("Analysis", "static dynamic") Analysis2 = enum.Enum("Analysis", "static dynamic") 

But:

 >>> Analysis1.static == Analysis2.static False 

This is because the equality operator is not defined for Enum objects, as far as I can tell, so the default id check behavior is used.

As @martineau notes in the comments, one way to avoid this problem is to use the IntEnum type, which subclasses int and therefore defines the equality operator in terms of the value of Enum , not id :

 import enum Analysis1 = enum.IntEnum("Analysis", "static dynamic") Analysis2 = enum.IntEnum("Analysis", "static dynamic") 

Then:

 >>> Analysis1.static == Analysis2.static True 

Why Enum and IntEnum ?

At first glance, it may seem that IntEnum always what we want. So what is the point of Enum ?

Suppose you want to list two sets of items, for example, fruits and colors. Now “orange” is both a fruit and a color. So we write:

 Fruits = enum.IntEnum("Fruits", "orange apple lemon") Colors = enum.IntEnum("Colors", "orange red blue") 

But now:

 >>> Fruits.orange == Colors.orange True 

But, philosophically speaking, “orange” (fruit) is not the same as “orange” (color)! Can't we tell them apart? Here, subclasses of int on IntEnum work against us, since both Fruits.orange and Colors.orange set to 1 . Of course, as we saw above, the Enum comparison compares id s, not values. Since Fruits.orange and Colors.orange are unique objects, they are not compared as equal:

 Fruits = enum.Enum("Fruits", "orange apple lemon") Colors = enum.Enum("Colors", "orange red blue") 

So, to:

 >>> Fruits.orange == Colors.orange False 

and we no longer live in a world where some colors are things you can find in the products section of your local grocery store.

+11
source

Source: https://habr.com/ru/post/981484/


All Articles