Is it possible to change the attribute value in the enum?

Question:

I need to reassign the attribute value in Enum.

from enum import Enum    

class Number(Enum):
    number = "1"
    
Number.number = "2" # AttributeError: cannot reassign member 'number'

I tried to reassign the attribute, but I got:

AttributeError: cannot reassign member ‘number’

Asked By: kurmo

||

Answers:

When using Enum, your number = "1" is considered as one of the enum entry.

So, firstly, it is thought to be used this way, for example :

from enum import Enum


class Number(Enum):
    numberOne = "1"
    numberTwo = "2"

By the way, when you access to Number.number, you access to the "enum item", which is more than just the value. The item has, indeed, a name (number) and a value ("1").

So, in theory, the good way to change the value should be :

Number.number.value = "2"

But, in any was, an Enum is made to not be mutable. So you can’t do that anyway.

Answered By: nabellaleen

Conceptually, an Enum is a way to give "nicer names" to "constants" and then use the nicer names in your code rather than using the constants.

This intent is implemented by Python by making the enum members as "functionally constant" … See Python Enum Documentation.

The names associated with Enums are not like variables.

Hence you cannot change the value of the name.

Answered By: Pravin Damle

Author’s note: This is a horrible idea.


Let’s just delete the string "1" from Python and replace it with "2"

from ctypes import c_byte
from enum import Enum
from sys import getsizeof


def change_enum_value(old: object, new: object) -> None:
    """
    Assigns contents of new object to old object.
    The size of new and old objection should be identical.

    Args:
        old (Any): Any object
        new (Any): Any object
    Raises:
        ValueError: Size of objects don't match
    Faults:
        Segfault: OOB write on destination
    """
    src_s, des_s = getsizeof(new), getsizeof(old)
    if src_s != des_s:
        raise ValueError("Size of new and old objects don't match")
    src_arr = (c_byte * src_s).from_address(id(new))
    des_arr = (c_byte * des_s).from_address(id(old))
    for index in range(len(des_arr)):
        des_arr[index] = src_arr[index]


class Number(Enum):
    number = "1"


change_enum_value(Number.number.value, "2")
print(Number.number.value)  # 2

You don’t have the "1" anymore, quite literally.

>>> "1"
'2'
>>>

which sure is a tad concerning…

Answered By: Achxy_

If you read the enum Python documentation:
The attributes, in your case Number.number, etc., are enumeration members (or members) and are functionally constants.

Answered By: Paul-ET
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.