Python 类装饰器-修改类字段也会更改基类中的值
我写了一个带有参数的类装饰器。此装饰器需要设置类字段Python 类装饰器-修改类字段也会更改基类中的值,python,python-decorators,Python,Python Decorators,我写了一个带有参数的类装饰器。此装饰器需要设置类字段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 __ini
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
中,首先我定义了从给定类类型派生的类,然后我修改了新\u Test
类的类名,并将其注册为当前模块中的全局类,然后(在最后一块中)在\u Test
类中设置ID
属性,并清除作为参数传递的类中的ID
,并返回新类型。我这样做是为了得到以下结果:
ID_Base
ID_Base_test
但是,在运行它之后,我看到:
ID_Base
ID_Base_test
ID_Base_test
为什么它修改派生的
类的属性而不是在decorator中创建的\u Test
?如何修复它
我使用Python2.6.6(Linux)和Python3.4.1(Windows上的ActivePython)对此进行了检查
编辑:我还尝试在\u Test
类中设置ID,如下所示,但得到了相同的结果:
def Test(cnt):
def createTest(className):
class _Test(className):
ID = className.ID + '_test'
从
print(Derived.ID)
中获得ID\u Base\u test
的原因是在装饰的末尾有一个隐式赋值,这使得Derived
引用了类派生的\u test
。以下代码
@Test(2)
class Derived(Base):
pass
相当于
class Derived(Base):
pass
Derived = Test(2)(Derived)
尝试打印(派生)
装饰完成后,您将获得\uuuuuu main\uuuuuu.Derived\u Test
更新:有关更多说明,请参阅
装饰器是用于修改函数、方法或类定义的任何可调用Python对象。装饰器被传递给正在定义的原始对象,并返回一个修改过的对象,,然后该对象被绑定到定义中的名称上
从
print(Derived.ID)
中获得ID\u Base\u test
的原因是在装饰的末尾有一个隐式赋值,这使得Derived
引用了类派生的\u test
。以下代码
@Test(2)
class Derived(Base):
pass
相当于
class Derived(Base):
pass
Derived = Test(2)(Derived)
尝试打印(派生)
装饰完成后,您将获得\uuuuuu main\uuuuuu.Derived\u Test
更新:有关更多说明,请参阅
装饰器是用于修改函数、方法或类定义的任何可调用Python对象。装饰器被传递给正在定义的原始对象,并返回一个修改过的对象,,然后该对象被绑定到定义中的名称上
你的测试来自哪里?他也有注释吗?派生的测试名称是在decorator中创建的,特别是在以下行中:
name=className.\uu\u name\uu+“\u Test”
\uu Test.\uu name\uu=name
globals()[name]=\u Test
派生的测试来自哪里?他也有注释吗?派生的测试名是在decorator中创建的,特别是在以下行中:name=className.\uu名\uu+“\u测试”
\uu名\uu=name
globals()[name]=\u测试
感谢您的解释,这很有意义。感谢您的解释,这很有意义。