设置多个方法以优于另一种方法的优雅方式

时间:2014-02-03 14:48:18

标签: python methods assign

我在课堂上有这个方法:

def do_exit():
  # some task

我想为do_exit分配一堆其他方法,所以目前我正在这样做:

do_quit = do_exit
do_stop = do_exit
do_finish = do_exit
do_complete = do_exit
do_leave = do_exit

这很好但我想知道是否有更好的方法,特别是如果我要做这么多。

3 个答案:

答案 0 :(得分:2)

您可以考虑制作一个字典来保存您的方法。使用defaultdict,您可以确保调用do_exit,如果没有其他任何内容插入特定函数名称的情况。另一方面,这可能不是非常安全或经过验证,例如:拼写错误:

from collections import defaultdict
method_dict = defaultdict(lambda: do_exit)

# Try this
method_dict["do_quit"]()

在课程中,如果您愿意,也可以覆盖__getattr__。说,只是猜测,所有这些方法都以do开头,否则可能的条件是它们以complete的某个同义词结尾。您可以为类提供一个类属性,该属性包含相应的约定项并检查它们,并根据需要在method_dict中查找它们。

from collections import defaultdict

class Foo(object):
    QUIT_WORDS = ['exit', 'quit', 'stop', 'finish', 'complete', 'leave']

    def __init__(self):
        self.method_dict = defaultdict(lambda: self.do_exit)

    def __getattr__(self, attr):
        if any([attr.endswith("_{}".format(x)) for x in self.QUIT_WORDS]):
            return self.method_dict[attr]
        else:
            return super(Foo, self).__getattribute__(attr)

    def do_exit(self):
        print "Exit!"

例如:

In [88]: f = Foo()

In [89]: f.do_quit()
Exit!

In [90]: f.do_exit()
Exit!

In [91]: f.do_go_bye_bye()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-91-2584940dee36> in <module>()
----> 1 f.do_go_bye_bye()

<ipython-input-87-3b0db0bf6a47> in __getattr__(self, attr)
     11             return self.method_dict[attr]
     12         else:
---> 13             return super(Foo, self).__getattribute__(attr)
     14 
     15 

答案 1 :(得分:0)

您的代码实际上是危险的:如果您继承了您的初始类,您将会遇到意外行为。请考虑以下事项:

class Foo(object):
    def m1(self):
        print "Hello!"

    m2 = m1


class Bar(Foo):
    def m1(self):
        print "World!"

# prints "World!", as expected
Bar().m1()

# prints "Hello!", because Bar.m2 is Foo.m2 is Foo.m1, *not* Bar.m1
Bar().m2()

不幸的是,对于不破坏继承的用例的唯一简单解决方案是手动定义每个方法,使用def foo(self): return self.bar()类型的构造。

答案 2 :(得分:-1)

你可以这样做:

do_quit = do_stop = do_finish = do_complete = do_leave = do_exit