【问题标题】:Python pass class instance to its method (function) decorators [closed]Python将类实例传递给它的方法(函数)装饰器[关闭]
【发布时间】:2017-05-30 03:09:21
【问题描述】:

我想做以下事情:
我有一个类,该类有一个名为 cmds 的字典。我想通过装饰器动态添加元素。装饰器应该是一个函数,这个类的一个方法。
我想要的示例代码:

class Foo(object):
    #In a class:
    @cmd("exit")
    def cmd_exit(self, *args):
        self.run=0
        print("Exiting mainloop...")
    @cmd('reconnect')
    def cmd_reconnect(self):
        self.connect(self._host)

为此,我需要将 self 传递给方法 cmd,这是一个装饰器。但是,cmd 不会收到 self
那么我该怎么做呢?
编辑:
我的Foo.cmd 方法有以下定义:

def cmd(self, name):
    def decorator(funcs):
       fname=name if name else funcs.__name__
          self.cmds[fname]=funcs
          self.cmdLogger.info("Registrated function %s", name)
          return
    return decorator

它只接收我传递给装饰器的字符串(例如“退出”和“重新连接”) 请注意,内部装饰器(称为装饰器)返回None,因此调用装饰器的原始函数被“删除”。

【问题讨论】:

  • 假设您的第一个代码块旨在嵌套在 class Foo: 块内(您应该添加它!):self 不仅还不存在,类本身也不存在.在class 块的顶层,您仍在定义该类应该包含的内容。所以当然你不能拥有那个类的实例。
  • @Kevin ...哦@Đ#đ,这就是问题所在。在定义方法时,我无法调用方法。但我可以稍后通过将cmd_ 函数移出类,并在它们上调用Foo.cmd(name) 来实现。我一定很累,我忽略了它。你应该写一个答案,这样我才能接受。

标签: python class methods decorator self


【解决方案1】:

您可以从另一个类继承“cmds”,以在“中心位置”跟踪您的日志:

from functools import wraps

def cmd(*name):
    def wrapper(fn):
        @wraps(fn)
        def real_decorator(*args, **kw):
            fname = name[0] if name else fn.__name__

            cls = args[0]
            cls.cmds[fname]=fn
            #self.cmdLogger.info("Registrated function %s", name)
            return fn(*args,**kw)
        return real_decorator
    return wrapper

class Logger(object):
    def __init__(self):
        self.cmds = {}
        #self.cmdLogger = ...

class Foo(Logger):
    @cmd("exit")
    def cmd_exit(self, *args):
        self.run=0
        print("Exiting mainloop...")

    @cmd('reconnect')
    def cmd_reconnect(self):
        self.connect(self._host)

f = Foo()
f.cmd_exit()
print(f.cmds)

返回:

Exiting mainloop...
{'exit': <function Foo.cmd_exit at 0x7fb11cfee048>}

【讨论】:

    猜你喜欢
    • 2017-11-12
    • 2019-05-24
    • 2013-03-10
    • 2016-01-30
    • 2023-03-05
    • 2021-08-20
    • 2021-08-22
    • 2021-11-15
    相关资源
    最近更新 更多