【发布时间】:2021-11-30 07:35:18
【问题描述】:
所以,我有一个这样的类的装饰器
def something_todo(f):
@functools.wraps(f)
def decorator(self, *args, **kwargs):
# do something
return f(self, *args, **kwargs)
return decorator
我想在装饰器中对self 参数进行类型注释。但是,这样写是行不通的
def something_todo(f):
@functools.wraps(f)
def decorator(self: SomeClass, *args, **kwargs):
# do something
return f(self, *args, **kwargs)
return decorator
class SomeClass:
def __init__(self):
# init here
@something_todo
def some_method(self, *args, **kwargs):
# some process
如果我用不同的脚本编写装饰器和类,情况会变得更糟。这很可能会发生
ImportError: cannot import name 'SomeClass' from partially initialized module 'someclass' (most likely due to a circular import)
我这样做的原因是为了清楚起见,以便人们知道我的装饰器仅适用于该类方法。此外,我可以在编辑器中轻松检查类的所有方法或属性,而无需打开包含该类的脚本。
编辑
所以这是解决方案的回顾:
假设我有 2 个脚本。一个包含class,一个包含装饰器函数。例如,
# inside decorators.py
def something_todo(f):
@functools.wraps(f)
def decorator(self, *args, **kwargs):
# do something
return f(self, *args, **kwargs)
return decorator
和
# inside someclass.py
from decorators import something_todo
class SomeClass:
def __init__(self):
# init here
@something_todo
def some_method(self, *args, **kwargs):
# some process
如果我想在装饰器中为self参数添加类型注释,我不能这样做
# inside decorators.py
from someclass import SomeClass
def something_todo(f):
@functools.wraps(f)
def decorator(self: SomeClass, *args, **kwargs):
# do something
return f(self, *args, **kwargs)
return decorator
因为当我尝试在另一个脚本中导入类时它会引发ImportError。所以,为了防止错误,我可以这样做
# inside decorators.py
from someclass import *
def something_todo(f):
@functools.wraps(f)
def decorator(self: "SomeClass", *args, **kwargs):
# do something
return f(self, *args, **kwargs)
return decorator
而且效果很好。
【问题讨论】:
-
“不工作”是什么意思?
-
PEP 612,参数规范变量是否解决了您的困难?
-
@Samwise 无法正常工作,好像它会引发我最后所说的错误。
标签: python annotations python-decorators