首页 > 解决方案 > 函数装饰器中的名称修饰

问题描述

如果装饰器名称是 __double_leading_underscore 类型,我不能在与装饰器相同的模块中声明的类中使用装饰器。

用一个例子更容易解释:

# Just a pass-through
def __decorator(fn):
  return fn

decorator = __decorator

class A(object):
  @decorator
  def test(self):
    return 1

print(A().test())
# Prints 1

如果我@decorator改变@__decorator

class A(object):
  @__decorator
  def test(self):
    return 1

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in A
NameError: name '_A__decorator' is not defined

它试图__decorator从类中查找。

有没有办法保持命名约定但引用模块而不是类?

标签: pythonpython-3.xpython-decorators

解决方案


这是由于 Python 的名称修改造成的。根据文档

__spam 形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为 _classname__spam,其中 classname 是去掉前导下划线的当前类名。只要它出现在类的定义中,就无需考虑标识符的句法位置,就可以完成这种修饰。

重点补充。

当解释器@__decorator在 class中看到时A,它会忽略对 的绑定decorator,用文本替换__decorator_A__decorator尝试评估标识符,从而为您提供NameError.


推荐阅读