C. *_*oew 11 python enums python-3.x
我注意到Python 3 Enums(链接)中的一个奇怪之处.
如果将Enum的值设置为函数,则会阻止将该属性包装为Enum对象,这会阻止您使用类似EnumCls['AttrName']动态加载属性的酷功能.
这是一个错误吗?有意进行了吗?
我搜索了一段时间,但没有提到你可以在枚举中使用的限制值.
以下是显示问题的示例代码:
class Color(Enum):
Red = lambda: print('In Red')
Blue = lambda: print('In Blue')
print(Color.Red) # <function> - should be Color.Red via Docs
print(Color.Blue) # <function> - should be Color.Bluevia Docs
print(Color['Red']) # throws KeyError - should be Color.Red via Docs
Run Code Online (Sandbox Code Playgroud)
此外,这是我第一次询问,所以让我知道是否有什么我应该做的不同!谢谢你的帮助!
Bre*_*arn 10
文件说:
允许的规则如下:
_sunder_名称(以单个下划线开头和结尾)由enum保留,不能使用; 枚举中定义的所有其他属性将成为此枚举的成员,但__dunder__名称和描述符除外(方法也是描述符).
"方法"只是在类体内定义的函数.无论您是用lambdaor 定义它都无关紧要def.所以你的例子是这样的:
class Color(Enum):
def Red():
print('In Red')
def Blue():
print('In Blue')
Run Code Online (Sandbox Code Playgroud)
换句话说,你声称的枚举值实际上是方法,因此不会成为枚举的成员.
如果有人需要/想要使用带有函数作为值的 Enum,可以通过使用可调用对象作为代理来实现,如下所示:
class FunctionProxy:
"""Allow to mask a function as an Object."""
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
return self.function(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
一个简单的测试:
from enum import Enum
class Functions(Enum):
Print_Function = FunctionProxy(lambda *a: print(*a))
Split_Function = FunctionProxy(lambda s, d='.': s.split(d))
Functions.Print_Function.value('Hello World!')
# Hello World!
Functions.Split_Function.value('Hello.World.!')
# ['Hello', 'World', '!']
Run Code Online (Sandbox Code Playgroud)
您可以将这些lambda包装在元组中并覆盖该__call__方法:
class Color(Enum):
red = (lambda text: '<font color=red>%s</font>' % text,)
blue = (lambda text: '<font color=blue>%s</font>' % text,)
def __call__(self, *args, **kwargs):
return self.value[0](*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
然后可以使用:
>>> Color.red('flowers')
<font color=red>flowers</font>
Run Code Online (Sandbox Code Playgroud)
您还可以使用functools.partial欺骗枚举不将您的函数视为以下方法Color:
from functools import partial
from enum import Enum
class Color(Enum):
Red = partial(lambda: print('In Red'))
Blue = partial(lambda: print('In Blue'))
Run Code Online (Sandbox Code Playgroud)
这样您就可以按预期name访问。value
Color.Red
Out[17]: <Color.Red: functools.partial(<function Color.<lambda> at 0x7f84ad6303a0>)>
Color.Red.name
Out[18]: 'Red'
Color.Red.value()
In Red
Run Code Online (Sandbox Code Playgroud)