如何解决自定义 __repr__ 作为从 Enum 派生的类的类方法
我有一个派生自 enum.Enum 的类。 现在 enum.Enum 中的 repr 指的是 enum.Enum 的成员,而不是整个类。
例如
from enum import Enum
class endpoints(Enum):
""" shop """
shop = 'shop'
countries = 'countries'
policies = 'policies'
print(endpoints)
结果
<enum 'endpoints'>
我尝试了什么
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)
结果
<enum 'endpoints'>
这表明repr实际上是endpoints.member。repr 我需要的是端点。repr?
我知道这可以通过元类 here 来实现,但是由于 Enum 本身有一个元类,我不能从另一个元类继承/分配。
停止修改 enum.Enum 我怎样才能实现我的目标。
所需的输出如下。
print(endpoints)
shop : shop
countries : countries
policies : policies/{object_id}
解决方法
要修改类对象的打印方式,就像对于任何对象一样,您需要修改它的类__repr__
,即元类__repr__
,而不是简单地装饰MyClass.__repr__
与 classmethod
。在这种情况下,您需要一个自定义的 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
基本上,
但由于 Enum 本身有一个元类,我不能从另一个元类继承/分配。
错了。你可以提供一个自定义元类如果它派生自基类的元类就好了,即使你的基类有一个元类。它必须以这种方式工作,因为所有类都有一个元类,默认情况下,type
。
3.3.3.3。确定合适的元类
-
如果没有给出基类和明确的元类,则使用
type()
; -
如果给出了显式元类并且它不是
type()
的实例,则直接将其用作元类; -
如果将
type()
的实例作为显式元类给出,或者定义了基类,则使用派生程度最高的元类。
从显式指定的元类(如果有)和所有元类(即type(cls)
)中选择最派生的元类
指定的基类。最派生的元类是一个
所有这些候选元类的子类型。
强调了。所以在这个简单的单继承情况下,由于 CustomEnumMeta
是 CustomEnumMeta
和 EnumMeta
之间派生最多的元类,所以它被用作元类。
__repr__
仅在类实例上调用,如 endpoints('shop')
而不是在类本身上调用。
或者,您可以使用自己的类方法来代替 __repr__
,例如 enum_members(cls)
,然后您可以在类本身而不是实例上调用这个自己的方法。
此外,您必须执行 print(repr(obj))
而不是仅使用 print(obj)
才能使用 __repr__
方法。如果您只想 print(obj)
,则创建 __str__
方法而不是 __repr__
。
使用 cls.__members__
代替 list(cls)
枚举所有枚举成员。
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 list(cls)])
print(repr(endpoints('shop')))
输出:
shop:shop
countries:countries
policies:policies/{object_id}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。