Nannan AV
Nannan AV

Reputation: 419

python enum.Enum _value_ vs value

from enum import Enum
class Type(Enum):
  a = 1
  b = 2

print Type.a.value, Type.a._value_

This prints

1 1

What is the difference between _ value_ and value?

Upvotes: 5

Views: 1794

Answers (2)

Ethan Furman
Ethan Furman

Reputation: 69021

The difference is that .value is the property-backed version and cannot be changed:

>>> from enum import Enum
>>> class Color(Enum):
...   red = 1
...   green = 2
...   blue = 3
... 
>>> Color.green
<Color.green: 2>
>>> Color.green.value
2
>>> Color(2)
<Color.green: 2>
>>> Color.green.value = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/types.py", line 141, in __set__
    raise AttributeError("can't set attribute")
AttributeError: can't set attribute

But ._value_ is where the actual value is stored in the instance-dict, and can be changed:

>>> Color.green._value_ = 4
>>> Color.green
<Color.green: 4>

As Tobias explained, names that begin with an underscore should be avoided unless you have a really good reason, as you can break things using them:

>>> Color(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/enum.py", line 241, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.5/enum.py", line 476, in __new__
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 4 is not a valid Color

Upvotes: 4

user1781434
user1781434

Reputation:

The docs are a bit unclear, but as I understand the docs, _value_ is only to be used to set the value if you write your own __new__ constructor. This will later result in value being set by the metaclass provided by the enum module.

https://docs.python.org/3/library/enum.html#supported-sunder-names

Per convention, names starting with an underscore are "private" members of a class so definitely go with .value.

Upvotes: 4

Related Questions