質問

I have this method in a class:

def do_exit():
  # some task

I want to assign a bunch of other methods to do_exit, so currently I'm doing this:

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

This works fine but I'm wondering if there's a better way, especially if I'm going to be doing this a lot.

役に立ちましたか?

解決

You might consider making a dictionary to hold your methods. With a defaultdict, you can ensure that do_exit is called if it's ever the case that nothing else was slotted in for a particular function name. On the other hand, this might not be very safe or validated against, e.g. spelling errors:

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

# Try this
method_dict["do_quit"]()

Within a class, you could also override __getattr__ if you'd like. Say, just guessing, that all of these kinds of methods begin with do or else maybe the condition is that they end with some synonym of complete. You could give the class a class attribute that holds the appropriate convention items and checks for them, and looks them up in method_dict as needed.

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!"

For example:

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 

他のヒント

Your code is actually dangerous: if you subclass your initial class, you'll get unexpected behavior. Consider the following:

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

Unfortunately, the only simple solution to your use case that doesn't break inheritance is to define each method manually, with a def foo(self): return self.bar() type of construct.

You can do:

do_quit = do_stop = do_finish = do_complete = do_leave = do_exit
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top