Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 类装饰器-修改类字段也会更改基类中的值_Python_Python Decorators - Fatal编程技术网

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测试
感谢您的解释,这很有意义。感谢您的解释,这很有意义。