Class 装饰器 - class 字段的修改也改变了基础 class 中的值
Class decorator - modification of class field changes value in base class too
我写了一个带参数的 class 装饰器。此装饰器需要设置 class 字段的值 ID
。我正在按照以下方式进行操作:
class Base:
ID = "ID_Base"
def __init__(self, n):
self.n = n
def func(self):
pass
def Test(cnt):
def createTest(className):
class _Test(className):
def __init__(self, n):
className.__init__(self, n)
def func(self):
for n in range(cnt):
className.func(self)
name = className.__name__ + "_Test"
_Test.__name__ = name
globals()[name] = _Test
_Test.ID = className.ID + '_test'
className.ID = ''
return _Test
return createTest
@Test(2)
class Derived(Base):
pass
print(Base.ID)
print(Derived.ID)
print(Derived_Test.ID)
在函数 createTest
中,首先我从给定的 class 类型派生了 class 的定义,然后我修改 class 新名称 _Test
class 并在当前模块中将其注册为全局 class,然后(在最后一个块中)我在 _Test
class 中设置 ID
属性并在 ID
中清除 ID
class 作为参数传递,return 新类型。我这样做是为了得到以下结果:
ID_Base
ID_Base_test
但是在 运行 之后我看到了这个:
ID_Base
ID_Base_test
ID_Base_test
为什么它修改 Derived
class 的属性而不是 _Test
在装饰器中创建的属性?以及如何修复它?
我使用 Python 2.6.6 (Linux) 和 Python 3.4.1 (ActivePython on Windows) 进行了检查。
编辑:我也尝试在 _Test
class 中设置 ID,如下所示,但得到了相同的结果:
def Test(cnt):
def createTest(className):
class _Test(className):
ID = className.ID + '_test'
你从 print(Derived.ID)
得到 ID_Base_test
的原因是在装饰的末尾有一个隐式赋值,这使得 Derived
引用 class Derived_Test
。下面的代码
@Test(2)
class Derived(Base):
pass
有点等于
class Derived(Base):
pass
Derived = Test(2)(Derived)
装饰后尝试print(Derived)
,你会得到__main__.Derived_Test
。
更新:请参阅 this wiki 了解更多说明。
A decorator is any callable Python object that is used to modify a function, method or class definition. A decorator is passed the original object being defined and returns a modified object, which is then bound to the name in the definition.
我写了一个带参数的 class 装饰器。此装饰器需要设置 class 字段的值 ID
。我正在按照以下方式进行操作:
class Base:
ID = "ID_Base"
def __init__(self, n):
self.n = n
def func(self):
pass
def Test(cnt):
def createTest(className):
class _Test(className):
def __init__(self, n):
className.__init__(self, n)
def func(self):
for n in range(cnt):
className.func(self)
name = className.__name__ + "_Test"
_Test.__name__ = name
globals()[name] = _Test
_Test.ID = className.ID + '_test'
className.ID = ''
return _Test
return createTest
@Test(2)
class Derived(Base):
pass
print(Base.ID)
print(Derived.ID)
print(Derived_Test.ID)
在函数 createTest
中,首先我从给定的 class 类型派生了 class 的定义,然后我修改 class 新名称 _Test
class 并在当前模块中将其注册为全局 class,然后(在最后一个块中)我在 _Test
class 中设置 ID
属性并在 ID
中清除 ID
class 作为参数传递,return 新类型。我这样做是为了得到以下结果:
ID_Base
ID_Base_test
但是在 运行 之后我看到了这个:
ID_Base
ID_Base_test
ID_Base_test
为什么它修改 Derived
class 的属性而不是 _Test
在装饰器中创建的属性?以及如何修复它?
我使用 Python 2.6.6 (Linux) 和 Python 3.4.1 (ActivePython on Windows) 进行了检查。
编辑:我也尝试在 _Test
class 中设置 ID,如下所示,但得到了相同的结果:
def Test(cnt):
def createTest(className):
class _Test(className):
ID = className.ID + '_test'
你从 print(Derived.ID)
得到 ID_Base_test
的原因是在装饰的末尾有一个隐式赋值,这使得 Derived
引用 class Derived_Test
。下面的代码
@Test(2)
class Derived(Base):
pass
有点等于
class Derived(Base):
pass
Derived = Test(2)(Derived)
装饰后尝试print(Derived)
,你会得到__main__.Derived_Test
。
更新:请参阅 this wiki 了解更多说明。
A decorator is any callable Python object that is used to modify a function, method or class definition. A decorator is passed the original object being defined and returns a modified object, which is then bound to the name in the definition.