oul*_*enz 6 python metaclass python-3.x python-decorators
是否可以修改一个类以使某个方法装饰器可用,而不必显式导入它而不必添加前缀(@something.some_decorator):
class SomeClass:
    @some_decorator
    def some_method(self):
        pass
我不认为这是可能的类装饰器,因为这应用太晚了.看起来更有希望的选项是使用元类,但我不确定如何,我的猜测是我必须some_decorator被引入到名称空间中SomeClass.
感谢@MartijnPieters指出staticmethod并且classmethod是内置插件.我原以为他们是type机器的一部分.
为了清楚起见,我没有任何明确的用例,我只是好奇这是否可能.
ADDENDUM,现在问题已得到解答.我之所以超越简单地在本地导入或定义装饰器的原因,是因为我定义了一个装饰器,只有在某个对象上初始化某个容器属性时才会起作用,而我正在寻找一种方法来强制执行此操作装饰的可用性.我最终检查属性是否存在,如果没有在装饰器中初始化它,这可能是这里较小的邪恶.
是的,在Python 3中,您可以使用元类__prepare__钩子.它应该返回一个映射,它构成了类体的本地命名空间的基础:
def some_decorator(f):
    print(f'Decorating {f.__name__}')
    return f
class meta(type):
    @classmethod
    def __prepare__(mcls, name, bases, **kw):
        return {'some_decorator': some_decorator}
class SomeClass(metaclass=meta):
    @some_decorator
    def some_method(self):
        pass
运行以上产生
Decorating some_method
但是,你不应该使用它.正如Python的Zen所说:显式优于隐式,并且在您的类中引入魔术名称很容易导致混淆和错误.导入元类与导入装饰器没有什么不同,您将一个名称替换为另一个名称.
在创建类主体后,类装饰器仍然可以将其他装饰器应用于类上的方法.该@decorator语法只是语法糖name = decorator(decorated_object),以后可以随时上应用装饰用name = decorator(name),或在一类背景下,作为cls.name = decorator(cls.name).如果您需要选择应该应用的方法,您可以选择方法名称,方法上设置的属性或方法的文档字符串等条件.或者直接在方法上使用装饰器.
| 归档时间: | 
 | 
| 查看次数: | 196 次 | 
| 最近记录: |