子类Python枚举中的重写方法
从子类化枚举开始,允许执行以下操作:子类Python枚举中的重写方法,python,python-3.x,enums,Python,Python 3.x,Enums,从子类化枚举开始,允许执行以下操作: >>> class Foo(Enum): ... def some_behavior(self): ... pass ... >>> class Bar(Foo): ... happy = 1 ... sad = 2 ... 假设我想以不同的方式为happy和sad枚举定义一些行为 有没有更好的方法可以做到这一点 >>> class Bar(Foo): ... happy = 1
>>> class Foo(Enum):
... def some_behavior(self):
... pass
...
>>> class Bar(Foo):
... happy = 1
... sad = 2
...
假设我想以不同的方式为happy
和sad
枚举定义一些行为
有没有更好的方法可以做到这一点
>>> class Bar(Foo):
... happy = 1
... sad = 2
... def some_behavior(self):
... if self is Bar.happy:
... # happy behavior
... elif self is Bar.sad:
... # sad behavior
我觉得那很笨重 没有
我的意思是,你也许可以这样做:
def some_behavior(self):
return {Bar.happy: some_function
Bar.sad: some_other_function}[self](arguments?)
def some_behavior(self):
custom_thing = {Bar.happy: some_function
Bar.sad: some_other_function}[self]
# do something which is the same for both
custom_thing()
# do something else the same for both
class Foo(Enum):
happy = 1
sad = 2
def happy_behavior(): # No self argument!
self = Foo.happy # only if you need self
...
def sad_behavior():
self = Foo.sad
...
Foo.happy.some_behavior = happy_behavior
Foo.sad.some_behavior = sad_behavior
或者像这样:
def some_behavior(self):
return {Bar.happy: some_function
Bar.sad: some_other_function}[self](arguments?)
def some_behavior(self):
custom_thing = {Bar.happy: some_function
Bar.sad: some_other_function}[self]
# do something which is the same for both
custom_thing()
# do something else the same for both
class Foo(Enum):
happy = 1
sad = 2
def happy_behavior(): # No self argument!
self = Foo.happy # only if you need self
...
def sad_behavior():
self = Foo.sad
...
Foo.happy.some_behavior = happy_behavior
Foo.sad.some_behavior = sad_behavior
但是,除非已经存在一些函数,否则这可能不会比您现在拥有的更好(尽管我想您可能能够保存一两级缩进)。您可以在这里使用lambdas,但它很快就会变得难看,我不推荐使用它,除非是在最简单的情况下(通常可以处理)
如评论中所述,您可以执行以下操作:
def some_behavior(self):
return {Bar.happy: some_function
Bar.sad: some_other_function}[self](arguments?)
def some_behavior(self):
custom_thing = {Bar.happy: some_function
Bar.sad: some_other_function}[self]
# do something which is the same for both
custom_thing()
# do something else the same for both
class Foo(Enum):
happy = 1
sad = 2
def happy_behavior(): # No self argument!
self = Foo.happy # only if you need self
...
def sad_behavior():
self = Foo.sad
...
Foo.happy.some_behavior = happy_behavior
Foo.sad.some_behavior = sad_behavior
在我看来,这相当难看,但它应该在所有合理的情况下都有效,包括像Foo(1).some\u behavior()
或Foo['sad'].some\u behavior()
这样的表达式。但是,它可能会混淆静态类型检查器和/或过梁。是的,有1个
诀窍在于覆盖\uuuu getattribute\uuuu
,这会拦截所有名称查找,并且非常危险2:
然后编写最后的枚举
:
class Bar(Foo):
#
# default methods
#
def some_behavior(self):
return self.name + ' is neutral'
def likes_to(self):
return 'likes to sit'
#
# members
#
@member
class happy:
# overridden methods
def some_behavior(self):
return self.name + ' is happy'
def likes_to(self):
return 'likes to dance'
@member
class sad:
# overridden method
def some_behavior(self):
return self.name + ' is sad'
@member
class okay:
# uses default methods
pass
在使用中:
>>> list(Bar)
[<Bar.happy>, <Bar.sad>, <Bar.okay>]
>>> Bar.happy.some_behavior()
'happy is happy'
>>> Bar.happy.likes_to()
'likes to dance'
>>> Bar.sad.some_behavior()
'sad is sad'
>>> Bar.sad.likes_to()
'likes to sit'
>>> Bar.okay.some_behavior()
'okay is neutral'
>>> Bar.okay.likes_to()
'likes to sit'
>>列表(条形图)
[, ]
>>>酒吧。快乐。一些行为()
“快乐就是快乐”
>>>酒吧。快乐。喜欢
“喜欢跳舞”
>>>酒吧。悲伤。一些行为()
“悲伤就是悲伤”
>>>酒吧。悲伤。喜欢
“喜欢坐”
>>>好吧,一些行为
“好的,是中立的”
>>>好吧,我喜欢
“喜欢坐”
1完全不惯用
2跳过\uuuuu getattribute\uuuuuu
是危险的,因为它控制属性的处理方式——例如,描述符魔术在对象中实现。这里的任何错误都可能导致难以调试的问题
披露:我是、和库的作者。测试枚举身份的标准方法是使用is
(例如self is Bar.happy
)。你不使用它有什么原因吗?你是对的。从长远来看,Lambdas不会有什么好处。一些类似Javascript的语法:happy.Some_behavior=def(){#dohappy stuff}
,在这里会很有用,它会退化为Python,除了lambdas之外没有匿名函数。实际上,您可以手动分配这样的函数,但这不是惯用的IMHO。所有Python函数都是一流的,不仅仅是lambdas。