Python 根据参数类型对类a调用方法
我不喜欢Python 根据参数类型对类a调用方法,python,oop,Python,Oop,我不喜欢manager()中的if/elif块查看和重构它的方式: class Class1(object): ... class Class2(object): ... class Class3(object): ... class A(object): def _methA(parm1, parm2) ... def _methB(parm1, parm2) ... def _methC(parm1,
manager()
中的if/elif
块查看和重构它的方式:
class Class1(object):
...
class Class2(object):
...
class Class3(object):
...
class A(object):
def _methA(parm1, parm2)
...
def _methB(parm1, parm2)
...
def _methC(parm1, parm2)
...
def manager(parm1, method, params)
...
if parm1.__class__.__name__==Class1.__name__:
response = _methA(parm1, params)
elif parm1.__class__.__name__==Class2.__name__:
response = _methB(parm1, params)
elif io_source.__class__.__name__==Class3.__name__:
response = _methC(parm1, params)
else:
raise Exception, "Unsupported parm1"
...
但是代码仍然在查看类名的事实让我很困扰-我真的不知道如何解释为什么这会困扰我吗?
是否有更好的方法编写代码来调用类a中的方法,该方法根据其参数之一的类触发对类a中不同方法的调用?
请原谅这个人为的例子,但是发布实际的代码会使问题更加复杂。我试图把这个问题提炼成它的本质…我更愿意
def manager(parm1, method, params)
...
try:
response = {
Class1.__name__: lambda parm1, parms: _methA(parm1, parms),
Class2.__name__: lambda parm1, parms: _methB(parm1, parms),
Class3.__name__: lambda parm1, parms: _methC(parm1, parms)
}[parm1.__class__.__name__](parm1, parms)
except KeyError:
raise Exception, "Unsupported parm1"
但这仍然有设计缺陷的味道。:)
也许你的三个类
ClassX
都应该有一个方法meth(params)
,那么你的经理就可以调用parm1.meth(params)
你正试图模仿语言极客们所说的“方法”或“多种方法”。链接到维基百科的文章进行了很好的讨论,包括Python示例。这是实现多态性的许多错误方法之一。你不应该看类名。查看类名会让您感到烦恼,因为这意味着您没有正确地委派职责
将每个方法移动到适当的类中
if isinstance(parm1, Class1):
_methA(parm1, params)
elif isinstance(parm1, Class2):
_methB(parm1, params)
elif isinstance(parm1, Class3):
_methC(parm1, params)
我通常在处理消息时这样做,所以我没有太多的假设。。。但它仍然使用类名 有点像穷人的多态性——但是,正如s.Lott所说,Python支持真正的多态性,所以为什么不使用它呢
class Class1(object):
def method( self, theA, params ):
theA.methA( params )
class Class2(object):
def method( self, theA, params ):
theA.methB( params )
class Class3(object):
def method( self, theA, params ):
theA.methC( params )
class A(object):
def methA(parm1, parm2)
...
def methB(parm1, parm2)
...
def methC(parm1, parm2)
...
def manager(parm1, method, params)
...
param1.method( self, params )
+1用于描述为什么我在查看类名时对代码感到不舒服。:-)是的,这是我们正在讨论的事情之一——为什么这些方法没有封装在Class1、Class2和Class3中。在实际的代码中,这是有原因的(尽管它们可能不是很好的原因)。@celopes:“它们可能不是很好的原因”——几乎是正确的。这些都不是很好的理由。他们“似乎”让
Class1
、Class2
和Class3
意识到A
的特性;但这一判断是错误的。A
的“隐藏”方法实际上是A
+1的公共界面:这是显示问题的最小代码片段的一个好例子。
class Handler(object):
# .. stuff
def dispatch(self, msg):
handlername = "on_%s" % type(msg)
return getattr(self, handlername, 'on_missing_handler')(msg)
def on_SomeClass(self, msg):
# msg is of SomeClass here ..
def on_SomeOtherClass(self, msg):
# msg is of SomeOtherClass here ..
def on_missing_handler(self, msg):
# there is no other handler for msg