允许python装饰器在传递的类中使用时将类作为参数

the*_*mms 4 python typechecking python-decorators

我在Python装饰器方面遇到了一些困难,我认为这与我将一个类作为参数传递给函数装饰器的事实有关,当被装饰的函数是传递类的方法时.

我没有比这更清楚的解释问题,所以希望一些代码可以帮助:

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)
    ...
Run Code Online (Sandbox Code Playgroud)

我不认为这个定义@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
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

我认为我的评论解释了我的想法:该类尚未定义(因为,​​我正在定义它),因此我无法通过它.

是否有一个整洁的解决方法不是:

assert isinstance(self, Vector), "Something is wrong... very wrong..."
Run Code Online (Sandbox Code Playgroud)

我知道我的类型检查超出了认为必要,但我想知道如何解决这类问题.

编辑:我也知道@accepts实际上并不是有效的Python.但是,这是我打算实现的代码的大纲.

Zer*_*eus 5

简短的回答是" 否",在完成定义之前,你不能像那样引用你的类.

类型检查是目前Python开发团队正在积极讨论的主题,并且在达成共识的范围内,功能注释是前进的方向:PEP 484描述了Guido想要实现它的方向.

该PEP中提出的前向引用的解决方法是仅使用字符串:

当类型提示包含尚未定义的名称时,该定义可以表示为字符串,以便稍后解析.例如,而不是写:

def notify_by_email(employees: Set[Employee]): ...
Run Code Online (Sandbox Code Playgroud)

有人可能写道:

def notify_by_email(employees: 'Set[Employee]'): ...
Run Code Online (Sandbox Code Playgroud)