允许 python 装饰器在被传递的 class 内部使用时将 class 作为参数
Allowing a python decorator to take a class as a parameter when used inside the class being passed
我在使用 Python 装饰器时遇到了一些困难,我认为这与我将 class 作为参数传递给函数装饰器有关,当函数被decorated 是传递 class 的一种方法。
我没有比这更清楚的问题解释了,所以希望一些代码能有所帮助:
from typeChecking import *
class Vector:
@accepts(Vector, float, float, float) #Vector hasn't been defined yet... In c++ I could forward declare...
def __init__(self, x, y, z):
self._x = float(x)
self._y = float(y)
self._z = float(z)
...
我认为 @accepts
的定义不重要,但为了以防万一,我还是把它留在这里:
def accepts(*types):
def check_accepts(f):
assert len(types) == f.func_code.co_argcount
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
new_f.func_name = f.func_name
return new_f
return check_accepts
我收到以下错误:
File "raytracerBase.py", line 41, in <module>
class Vector:
File "raytracerBase.py", line 42, in Vector
@accepts(Vector, float, float, float)
NameError: name 'Vector' is not defined
我认为我的评论解释了我认为正在发生的事情:class 尚未定义(因为,我正在定义它),因此我不能通过它。
是否有一个巧妙的解决方法不是:
assert isinstance(self, Vector), "Something is wrong... very wrong..."
我知道我进行的类型检查超出了必要的范围,但我还是想知道如何解决此类问题。
编辑: 我也知道 @accepts
实际上无效 Python。但是,这是我打算实现的代码大纲。
简短的回答是否,在完成定义之前,您不能那样引用您的class。
类型检查是 Python 开发团队目前正在积极讨论的主题,就达成共识而言,function annotations are the way forward: PEP 484 描述了 Guido 想要采取的方向在实施中。
该 PEP 中前向引用 proposed 的解决方法是仅使用字符串代替:
When a type hint contains names that have not been defined yet, that definition may be expressed as a string, to be resolved later. For example, instead of writing:
def notify_by_email(employees: Set[Employee]): ...
one might write:
def notify_by_email(employees: 'Set[Employee]'): ...
我在使用 Python 装饰器时遇到了一些困难,我认为这与我将 class 作为参数传递给函数装饰器有关,当函数被decorated 是传递 class 的一种方法。
我没有比这更清楚的问题解释了,所以希望一些代码能有所帮助:
from typeChecking import *
class Vector:
@accepts(Vector, float, float, float) #Vector hasn't been defined yet... In c++ I could forward declare...
def __init__(self, x, y, z):
self._x = float(x)
self._y = float(y)
self._z = float(z)
...
我认为 @accepts
的定义不重要,但为了以防万一,我还是把它留在这里:
def accepts(*types):
def check_accepts(f):
assert len(types) == f.func_code.co_argcount
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
new_f.func_name = f.func_name
return new_f
return check_accepts
我收到以下错误:
File "raytracerBase.py", line 41, in <module>
class Vector:
File "raytracerBase.py", line 42, in Vector
@accepts(Vector, float, float, float)
NameError: name 'Vector' is not defined
我认为我的评论解释了我认为正在发生的事情:class 尚未定义(因为,我正在定义它),因此我不能通过它。
是否有一个巧妙的解决方法不是:
assert isinstance(self, Vector), "Something is wrong... very wrong..."
我知道我进行的类型检查超出了必要的范围,但我还是想知道如何解决此类问题。
编辑: 我也知道 @accepts
实际上无效 Python。但是,这是我打算实现的代码大纲。
简短的回答是否,在完成定义之前,您不能那样引用您的class。
类型检查是 Python 开发团队目前正在积极讨论的主题,就达成共识而言,function annotations are the way forward: PEP 484 描述了 Guido 想要采取的方向在实施中。
该 PEP 中前向引用 proposed 的解决方法是仅使用字符串代替:
When a type hint contains names that have not been defined yet, that definition may be expressed as a string, to be resolved later. For example, instead of writing:
def notify_by_email(employees: Set[Employee]): ...
one might write:
def notify_by_email(employees: 'Set[Employee]'): ...