代码之家  ›  专栏  ›  技术社区  ›  cethegeek

根据参数类型在类A上调用方法

  •  4
  • cethegeek  · 技术社区  · 15 年前
    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中的一个方法,该方法根据其参数之一的类触发对中不同方法的调用。

    对这个人为的例子感到抱歉,但是发布实际的代码会使问题更加复杂。我试图将这个问题提炼成它的本质…

    4 回复  |  直到 14 年前
        1
  •  5
  •   S.Lott    15 年前

    这是实现多态性的许多错误方法之一。你不应该看类名。查看类名会让你很困扰,因为这意味着你没有正确地委派职责。

    将每个方法移动到适当的类中。

    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 )
    
        2
  •  1
  •   Jonathan Feinberg    15 年前

    你在模仿那些语言怪人所说的 multiple dispatch 或“多方法”。链接到维基百科的文章有一个很好的讨论,包括python示例。

        3
  •  0
  •   Johannes Charra    15 年前

    我宁愿

    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) .

        4
  •  0
  •   Jochen Ritzel    15 年前

    我通常在处理消息时这样做,所以我没有大量的if…但是它仍然使用类名。

    有点像穷人的多态性——但是,正如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