python - 类级装饰器

标签 python class decorator

我正在尝试使用以下代码进行某种类型处理函数注册:

types = {}
def type_handler(name):
    def wrapper(f):
        types[name] = f
        return f
    return wrapper

@type_handler('a')
def handle_a(a):
    ...

@type_handler('b'):
def handle_b(b):
    ...

def handle(x):
    types[x.name](x)

这工作正常,但现在我希望它在类中工作。
我试过这个:

class MyClass(object):

    types = {}
    def type_handler(name):
        def wrapper(f):
            types[name] = f ## global name 'types' is undefined
            return f
        return wrapper

    @type_handler('a')
    def handle_a(self, a):
        ...

    @type_handler('b'):
    def handle_b(self, b):
        ...

    def handle(self, x):
        self.types[x.name](self, x)

但它说全局名称“类型”未定义
我尝试将其更改为

    def type_handler(name):
        def wrapper(f):
            MyClass.types[name] = f ## global name 'MyClass' is undefined
            return f
        return wrapper

但现在它说全局名称“MyClass”未定义
我该怎么做才能使这项工作成功?

我知道我可以做这样的事情:

def handle(self, x):
    self.__getattribute__('handle_%s' % x.name)(self, x)

但我更喜欢函数注册而不是基于名称的查找。

最佳答案

我同意斯文·马尔纳克的观点。你应该使用“更少的魔法”。不过,这里有一个快速修复方法:

#decorator is declared outside of class and type dict is passed in as an argument
def type_handler(name, type_dict):
    def wrapper(f):
        type_dict[name] = f
        return f
    return wrapper

class MyClass(object):

    types = {}

    @type_handler('a', types)
    def foo_a(self, a):
        pass

    @type_handler('b', types)
    def foo_b(self, b):
        pass

版本 2

这个使用类作为装饰器:

class TypeHandler(object):
    def __init__(self, type_dict):
        self.types = type_dict

    def __call__(self, name):
        def wrapper(f):
            self.types[name] = f
            return f
        return wrapper


class MyClass(object):
    types = {}
    thandle = TypeHandler(types)

    @thandle('a')
    def foo_a(self, a):
        pass

关于python - 类级装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11899648/

相关文章:

python - 修改包装函数中的函数代码

node.js - NestJs - 从自定义装饰器内的服务调用方法

Python Dict 和 Forloop 以及 FASTA 文件

python - 使用 Python 进行网页抓取

python - false 未定义

javascript - 改变一个元素的样式而不改变另一个?

Python - 为什么 __str__ 在调用时想要返回一些东西?我在 __str__ 中有打印函数

java - java类加载器可以多次加载一个类吗

php - 如何在 PHP 中实现装饰器?

python - 无法在 Python 中将第二行添加到字典中