oul*_*enz 6 python metaclass python-3.x python-decorators
是否可以修改一个类以使某个方法装饰器可用,而不必显式导入它而不必添加前缀(@something.some_decorator
):
class SomeClass:
@some_decorator
def some_method(self):
pass
Run Code Online (Sandbox Code Playgroud)
我不认为这是可能的类装饰器,因为这应用太晚了.看起来更有希望的选项是使用元类,但我不确定如何,我的猜测是我必须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
Run Code Online (Sandbox Code Playgroud)
运行以上产生
Decorating some_method
Run Code Online (Sandbox Code Playgroud)
但是,你不应该使用它.正如Python的Zen所说:显式优于隐式,并且在您的类中引入魔术名称很容易导致混淆和错误.导入元类与导入装饰器没有什么不同,您将一个名称替换为另一个名称.
在创建类主体后,类装饰器仍然可以将其他装饰器应用于类上的方法.该@decorator
语法只是语法糖name = decorator(decorated_object)
,以后可以随时上应用装饰用name = decorator(name)
,或在一类背景下,作为cls.name = decorator(cls.name)
.如果您需要选择应该应用的方法,您可以选择方法名称,方法上设置的属性或方法的文档字符串等条件.或者直接在方法上使用装饰器.
归档时间: |
|
查看次数: |
196 次 |
最近记录: |