我试图创建一个decorator,该decorator在函数和它将响应执行的关联文本之间创建一个关联。下面是一些工作代码,说明了我的意思:

# WORKING CODE
mapping = {}

def saying(text):
        def decorator(function):
            mapping[text] = function
            return function
        return decorator

@saying("hi")
def hi():
    print "hello there"

@saying("thanks")
@saying("gracias")
def thanks():
    print "you're welcome"

mapping["hi"]() #running this line will print "hello there"
mapping["thanks"]() #running this line will print "you're welcome"

当我试图将这些方法添加到类中时,就会出现此问题。像这样的:
#NON-WORKING CODE:
class politeModule(object):
    def __init__(self):
        self.mapping = {}

    @saying("hi")
    def hi(self):
        print "hello there"

    @saying("thanks")
    @saying("gracias")
    def thanks(self):
        print "you're welcome"

module = politeModule()
module.mapping["hi"]()
module.mapping["thanks"]()

问题是,我不知道把decorator放在哪里,这样它就可以访问mapping并且也可以工作。我知道有很多关于StackOverflow的问题和文章。我试图实现this博客文章中描述的一些解决方案,但在范围界定问题和从decorator内部访问映射字典上屡屡遇到困难

最佳答案

寄存器装饰器
首先,当使用decorator作为函数的寄存器时,一个好的选择是为decorator编写一个类,以便它可以用于注册和访问已注册的函数。

class RegisterDecorator(object):
    def __init__(self):
        self._register = {}

    def __getitem__(self, item):
        return self._register[item]

    def register(self, text):
        def wrapper(f):
            self._register[text] = f
            return f
        return wrapper

saying = RegisterDecorator()

@saying.register('hello')
def f():
    print('Hello World')

saying['hello']() # prints 'Hello World'

注册类中的方法
以上方法对注册方法有效。尽管如此,它将只注册未绑定的方法。这意味着您必须手动传递self参数。
saying = Saying()

class PoliteModule(object):
    @saying.register("hi")
    def hi(self):
        print("hello there")

saying['hi'](PoliteModule()) # prints: 'hello there'

saying['hi']() # TypeError: hi() missing 1 required positional argument: 'self'

注册绑定方法
注册绑定方法不能在类实例化中完成,因为还没有实例存在。您必须创建一个实例并注册其绑定方法。
saying = Saying()

class PoliteModule(object):
    def hi(self):
        print("hello there")

politeInstance = PoliteModule()

saying.register("hi")(politeInstance.hi)

saying["hi"]() # prints: hello there

关于python - 难以让装饰器在python的类中工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50855495/

10-12 07:11