I have a class which is derived from enum.Enum. Now repr in enum.Enum refers to the member of the enum.Enum not the entire class.
For Example
from enum import Enum
class endpoints(Enum):
""" shop """
shop = 'shop'
countries = 'countries'
policies = 'policies'
print(endpoints)
Result
<enum 'endpoints'>
What I tried
from enum import Enum
class endpoints(Enum):
shop = 'shop'
countries = 'countries'
policies = 'policies/{object_id}'
@classmethod
def __repr__(cls):
return '\n'.join([str(member.name) + ':' + (member.value) for member in cls.__members__])
print(endpoint)
Result
<enum 'endpoints'>
This indicates that repr is effectively endpoints.member.repr what I need is endpoint.repr?
I understand this can be achieved by a metaclass here, but since Enum itself has a metaclass, I cannot inherit/assign from another metaclass.
stopping short of modifying enum.Enum how can I achieve my objective.
The desired output is as follows.
print(endpoints)
shop : shop
countries : countries
policies : policies/{object_id}
To modify a the way a class object is printed, like for any object, you need to modify it's classes __repr__
, i.e. the metaclass __repr__
, not simply decorate MyClass.__repr__
with classmethod
. In this case, you need a custom EnumMeta
:
In [1]: from enum import EnumMeta, Enum
In [2]: class CustomEnumMeta(EnumMeta):
...: def __repr__(self):
...: return '\n'.join([f"{name}: {value}" for name, value in self.__members__.items()])
...:
In [3]: class Endpoints(Enum, metaclass=CustomEnumMeta):
...: shop = 'shop'
...: countries = 'countries'
...: policies = 'policies'
...:
In [4]: Endpoints
Out[4]:
shop: Endpoints.shop
countries: Endpoints.countries
policies: Endpoints.policies
Basically,
but since Enum itself has a metaclass, I cannot inherit/assign from another metaclass.
Is wrong. You can provide a custom metaclass if it derives from the bases' metaclass just fine even if your base class has a metaclass. It has to work this way because all classes have a metaclass, by default, type
.
From the documentation:
3.3.3.3. Determining the appropriate metaclass
if no bases and no explicit metaclass are given, then
type()
is used;if an explicit metaclass is given and it is not an instance of
type()
, then it is used directly as the metaclass;if an instance of
type()
is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used.The most derived metaclass is selected from the explicitly specified metaclass (if any) and the metaclasses (i.e.
type(cls)
) of all specified base classes. The most derived metaclass is one which is a subtype of all of these candidate metaclasses.
Emphasis added. So in this simple case of single inheritance, since CustomEnumMeta
is the most derived metaclass between CustomEnumMeta
and EnumMeta
, then it is used as the metaclass.