Python Forum
Having trouble writing an Enum with a custom __new__ method
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Having trouble writing an Enum with a custom __new__ method
#1
Question 
I have an enum subclass where I need to associate two pieces of data with each enum. The first is used for the enum value itself, the second needs to be stored as an attribute.

Here is an example showing what I am trying to do:

from enum import Enum
class MyEnum(Enum):
    MEMBER = ("This is my enum", 1.5)
    def __new__(cls, value, extra):
        obj = super().__new__(cls, value)
        obj._value_ = value
        obj.extra = extra
        return obj
What I expect to get is this:

MyEnum.MEMBER.value == "This is my enum"  # This should return True
MyEnum.MEMBER.extra == 1.5  # This should return True
But instead, I get this error:

Error:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.10/enum.py", line 288, in __new__ enum_member = __new__(enum_class, *args) File "<stdin>", line 4, in __new__ File "/usr/local/lib/python3.10/enum.py", line 701, in __new__ raise ve_exc ValueError: 'This is my enum' is not a valid MyEnum
What is the right way to override __new__ in an Enum?

I have read the docs, but they only show an example where you are subclassing another class as well as Enum:

https://docs.python.org/3/library/enum.h...ew-vs-init
Reply
#2
From the docs you referenced:
Output:
When to use __new__() vs. __init__() __new__() must be used whenever you want to customize the actual value of the Enum member. Any other modifications may go in either __new__() or __init__(), with __init__() being preferred.
In other words use __new__ when you want to an enum that has a different type of value. Their example used bytes. Your value is a str.
class MyEnum(str, Enum):
    def __new__(cls, value, extra):
        obj = str.__new__(cls, [value])
        obj._value_ = value
        obj.extra = extra
        return obj

    MEMBER = ("This is my enum", 1.5)

print(MyEnum.MEMBER)
print(MyEnum.MEMBER.value)
print(MyEnum.MEMBER.extra)
Output:
MyEnum.MEMBER This is my enum 1.5
You were trying to create a new enum whose value was your new enum class.
stevendaprano likes this post
Reply
#3
Thanks deanhystad, but my enums shouldn't be a string subclass.
I think I have found a solution thanks to this blog post.

from enum import Enum

class MyEnum(Enum):
	MEMBER = ("Hello world", 1.5)
	def __new__(cls, value, extra):
		obj = object.__new__(cls)  # Don't use super(), use object
		obj._value_ = value
		obj.extra = extra
		return obj
Reply
#4
Why not? Their value is a string. If I want an enum that has integer values I used use an IntEnum.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Variable sorting methods for Enum DataClasses koen 1 777 May-30-2023, 07:31 PM
Last Post: deanhystad
  Custom method to handle exceptions not working as expected gradlon93 3 1,038 Dec-22-2022, 07:12 PM
Last Post: deanhystad
  Alarm system with state, class, enum. Frankduc 0 1,270 May-04-2022, 01:26 PM
Last Post: Frankduc
  Enum help SephMon 3 1,506 Nov-19-2021, 09:39 AM
Last Post: Yoriz
Smile Set 'Time' format cell when writing data to excel and not 'custom' limors 3 6,324 Mar-29-2021, 09:36 PM
Last Post: Larz60+
  Trouble writing over serial EngineerNeil 1 2,639 Apr-07-2019, 08:17 PM
Last Post: j.crater
  enum from typelib Erhy 2 2,160 Jan-26-2019, 05:37 PM
Last Post: Erhy
  Python error? Enum and strings tycarac 3 3,584 Dec-15-2018, 10:39 AM
Last Post: tycarac
  trouble writing to file after while loop Low_Ki_ 21 13,433 Jan-10-2017, 06:44 AM
Last Post: micseydel

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020