Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 根据参数类型对类a调用方法_Python_Oop - Fatal编程技术网

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