208

I have the following enum defined:

from enum import Enum
class D(Enum):
    x = 1
    y = 2

print(D.x)

now the printed value is

D.x

instead, I wanted the enum's value to be print

1

What can be done to achieve this functionality?

codeforester
  • 34,080
  • 14
  • 96
  • 122
Vaibhav Mishra
  • 10,622
  • 12
  • 43
  • 56
  • 1
    I should clarify the access parameters, I know the D.x.value thing, what I want is D.x string conversion to return the value, sorry if question doesn't make the condition clear. – Vaibhav Mishra Jun 30 '14 at 10:15

5 Answers5

345

You are printing the enum object. Use the .value attribute if you wanted just to print that:

print(D.x.value)

See the Programmatic access to enumeration members and their attributes section:

If you have an enum member and need its name or value:

>>>
>>> member = Color.red
>>> member.name
'red'
>>> member.value
1

You could add a __str__ method to your enum, if all you wanted was to provide a custom string representation:

class D(Enum):
    def __str__(self):
        return str(self.value)

    x = 1
    y = 2

Demo:

>>> from enum import Enum
>>> class D(Enum):
...     def __str__(self):
...         return str(self.value)
...     x = 1
...     y = 2
... 
>>> D.x
<D.x: 1>
>>> print(D.x)
1
Martijn Pieters
  • 963,270
  • 265
  • 3,804
  • 3,187
  • When I compare it with a integer value, it returns as object. Ex: `if D.x == 10: ...`. What approach should I take for integers? – alper Apr 24 '20 at 18:49
  • 1
    @alper: exactly the same way; `D.x` is the enum object, `D.x.value` is an integer value. If you must have the enum values act like integers, use the [`IntEnum` type](https://docs.python.org/3/library/enum.html#intenum), where each element is a subclass of `int` and so `IntEnumD.x == 10` would work. – Martijn Pieters Apr 26 '20 at 12:05
  • I have added `def __eq__(self, other): return int(self.value) == other` and `def __int__(self): return int(self.value)` but still I think I have to use `.value` on cases when I don't use comparing – alper Apr 26 '20 at 12:10
  • 1
    @alper: that `__eq__` implementation doesn't work when `other` is another enum value; `D.x == D.y`, where `D.x.value == D.y.value` would be true, would fail for example. It sounds like you want to use `IntEnum` instead of `Enum` there. – Martijn Pieters Apr 26 '20 at 12:30
  • .value is really annoying since it pollutes your code with a bunch of .value. A solution without .value would be great. I am still using Enum by principle (more precisely, class MyEnumClass(str, Enum): ...) but I must admit I prefer the use of a constants class since I can avoid the .value pollution. – Greg7000 Mar 28 '22 at 17:42
  • 1
    @Greg7000: what are you using `.value` *for*? If you have a `...(str, Enum)` enum, your members are already strings so anything that accepts a string can use that directly for most contexts. E.g. `f"The member is: {MyEnumClass.membername}"`, etc. You can always add your own `__str__` method for those contexts that call `.__str__()` (like print()). – Martijn Pieters Mar 30 '22 at 11:18
  • @Martijn Pieters, you are right I was wrong. At some point in time I faced a context where not using .value caused me an issue but this was either invalid or a twisted case. Thx for the remark. – Greg7000 Mar 30 '22 at 14:18
20

I implemented access using the following

class D(Enum):
    x = 1
    y = 2

    def __str__(self):
        return '%s' % self.value

now I can just do

print(D.x) to get 1 as result.

You can also use self.name in case you wanted to print x instead of 1.

Community
  • 1
  • 1
Vaibhav Mishra
  • 10,622
  • 12
  • 43
  • 56
  • 6
    Why the string formatting and `self._value_`? `return str(self.value)` is more straightforward. – Martijn Pieters Jun 30 '14 at 10:18
  • 1
    I just looked at the source and this was how it is implemented, however you are right and `self.value` is cleaner. – Vaibhav Mishra Jun 30 '14 at 10:20
  • 3
    The single-underscore attributes are internal to the generated enum class; better stick to the documented attribute (which happens to be a special descriptor so that you can still use `value` as a name on your enum type). – Martijn Pieters Jun 30 '14 at 10:28
5

If you are going to print value using f-string then you can inherit your enum from both Enum and str. For instance:

from enum import Enum


class D(str, Enum):
    x = 1
    y = 2


print(D.x)
print(f"{D.x}")

Outputs:

D.x
1
Vlad Bezden
  • 72,691
  • 22
  • 233
  • 168
2

The most straightforward dunder method to use is _repr_ instead of _str_ since it will also allow you to print it in that way also in lists.

class D(Enum):
  x = 1
  y = 2

  def __repr__(self):
      return self.value

print([D.x,D.y])
>>> [1, 2]
1

In case you want to compare your enum members to Int values, a better way to do it would be to extend IntEnum:

from enum import IntEnum


class D(IntEnum):
    x = 1
    y = 2


print(D.x)

In this way you can compare values of your enum against integers without explicitly calling .value:

>>> D.x == 1
True

For more information you can check this part of the Python docs: Enum comparisons

Julian
  • 1,621
  • 23
  • 14
  • I guess this answer should be the correct solution since the answer of @Martijn Pieters returns the “position value” which happens to be identical with the assign value. If x would be assigned to 5, `D.x` would return 1 anyways and not 5. – Ling Mar 25 '22 at 18:27