代码之家  ›  专栏  ›  技术社区  ›  Mike Trpcic

基于参数动态调用嵌套函数

  •  2
  • Mike Trpcic  · 技术社区  · 14 年前

    如果我有以下Python类:

    class Test(object):
        funcs = {
            "me"    : "action",
            "action": "action",
            "say"   : "say",
            "shout" : "say"
        }
    
        def dispatch(self, cmd):
            def say:
                print "Nested Say"
    
            def action:
                print "Nested Action"
    
            # The line below gets the function name as a string,
            # How can I call the nested function based on the string?
            Test.funcs.get(cmd, "say")
    

    我希望能够做到以下几点:

    >>> Test().dispatch("me")
    Nested Action
    >>> Test().dispatch("say")
    Nested Say
    

    关于我该怎么做有什么建议吗?

    2 回复  |  直到 14 年前
        1
  •  4
  •   aaronasterling    14 年前

    我可能会这样做:

    def register(dict_, *names):
        def dec(f):
            m_name = f.__name__
            for name in names:
                dict_[name] = m_name
            return f
        return dec
    
    class Test(object):
    
        commands = {}
    
        @register(commands, 'foo', 'fu', 'fOo')
        def _handle_foo(self):
            print 'foo'
    
        @register(commands, 'bar', 'BaR', 'bAR')
        def _do_bar(self):
            print 'bar'
    
        def dispatch(self, cmd):
            try:
                return getattr(self, self.commands[cmd])()
            except (KeyError, AttributeError):
                # Command doesn't exist. Handle it somehow if you want to
                # The AttributeError should actually never occur unless a method gets 
                # deleted from the class
    

    现在,这个类暴露了 dict 其密钥是用于测试成员资格的命令。所有方法和字典只创建一次。

    t = Test()
    
    if 'foo' in t.commands:
        t.dispatch('foo')
    
    for cmd in t.commands:
        # Obviously this will call each method with multiple commands dispatched to it once
        # for each command
        t.dispatch(cmd)
    

    等。

        2
  •  2
  •   aaronasterling    14 年前
    class Test(object):
    
        def dispatch(self):
            def say():
                print "Nested Say"
    
            def action():
                print "Nested Action"
    
            funcs = {
                "me"    : action,
                "action": action,
                "say"   : say,
                "shout" : say
            }
    
            Test.funcs.get(cmd, say)()
    

    或者,保持你目前的结构:

    class Test(object):
    
        funcs = {
            "me"    : "action",
            "action": "action",
            "say"   : "say",
            "shout" : "say"
            }
    
        def dispatch(self, cmd):
            def say():
                print "Nested Say"
    
            def action():
                print "Nested Action"
    
            locals()[Test.funcs.get(cmd, "say")]()
    

    不过,我觉得这个设计有点奇怪。为什么类级别的dict应该知道dispatch的本地函数?