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"
...
我不喜欢if/elif
中manager()
阻止查看并重构的方式:
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"
但是代码仍然在看类名的事实困扰着我 - 我真的不知道如何解释原因...... 它应该打扰我吗?
有没有更好的方法来编写代码在A类中调用一个方法,根据其中一个参数的类,它会触发A中不同方法的调用?
PS。对于人为的例子感到抱歉,但发布实际代码会让问题更加复杂。我试图将问题提炼到其本质......
答案 0 :(得分:5)
这是实现多态的许多错误方法之一。你永远不应该看班级名称。查看班级名称应该打扰你,因为这意味着你没有正确地委派责任。
将每个方法移动到适当的类中。
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 :(得分:1)
您试图模仿极客称之为“multiple dispatch”或“多方法”的语言。链接到维基百科的文章有很好的讨论,包括Python示例。
答案 2 :(得分:0)
我更喜欢
if isinstance(parm1, Class1):
_methA(parm1, params)
elif isinstance(parm1, Class2):
_methB(parm1, params)
elif isinstance(parm1, Class3):
_methC(parm1, params)
但这仍然有点设计缺陷。 :)
也许您的三个班级ClassX
应该只有一个方法meth(params)
,然后您的经理可以拨打parm1.meth(params)
。
答案 3 :(得分:0)
我通常在处理消息时这样做,所以我没有大量的ifs ......但它仍然使用类名。
一种穷人的多态性 - 但正如S.Lott所说,Python支持真正的多态,所以为什么不使用它:p
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