【问题标题】:Python, executing extra code at method definitionPython,在方法定义处执行额外代码
【发布时间】:2013-12-05 03:09:29
【问题描述】:

我正在编写一个 python API/服务器,以允许外部设备(微控制器)通过发送带有方法名称的字符串来远程调用对象的方法。这些方法将存储在字典中。例如:

class Server:
    ...
    functions = {}
    def register(self, func):
        self.functions[func.__name__] = func
    def call(self, func_name, args):
        self.functions[func_name](*args)
    ...

我知道我可以在类定义外部定义函数并手动注册它们,但我真的希望注册步骤能够自动完成。考虑以下类:

class MyServer(Server):
    ...
    def add(self,a,b):
        print a+b
    def sub(self,a,b):
        print a-b
    ...

它可以通过子类化服务器类和定义要调用的方法来工作。我怎样才能让方法在函数字典中自动注册?

我认为可以做到的一种方法是使用元类查看方法名称中的模式添加如果找到匹配项,则将该方法添加到函数字典中。好像有点矫枉过正...

是否可以装饰要注册的方法?有人可以给我提示一下这个问题的最简单解决方案吗?

【问题讨论】:

  • 您的元类解决方案也可以使用类装饰器来完成。方法上的装饰器将无法在类上存储任何内容,因为在方法装饰器运行时该类还不存在。
  • @BrenBarn 有a solution to that issue
  • @Lattyware:当然,我只是说除了方法上的装饰器之外,您还需要一些机器。

标签: python oop decorator metaclass


【解决方案1】:

无需构造字典,使用the getattr() built-in function即可:

   def call(self, func_name, args):
        getattr(self, func_name)(*args)

Python 实际上使用字典来访问对象的属性(它被称为 __dict__,但使用 getattr() 比直接访问要好)。

如果您出于某种原因真的想构造该字典,请查看the inspect module

def __init__(self, ...):
    self.functions = dict(inspect.getmembers(self, inspect.ismethod))

如果你想选择特定的方法,你可以使用装饰器来做到这一点,但正如 BrenBarn 指出的那样,在方法被装饰时实例并不存在,所以你需要使用 the mark and recapture technique 来做你想要什么。

【讨论】:

  • 确实,这将是一个更好的方法。但是,我如何打印 MyServer 中定义的方法列表而不将它们存储在列表中并遍历该列表?
  • @Speccy 如果您想要所有方法的列表,请查看inspect.getmembers() - 我的答案的后半部分。
猜你喜欢
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2019-01-21
  • 2014-06-02
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
相关资源
最近更新 更多