如何在Python中复制未初始化类以避免引用共享?
如何完全复制Python类,避免类变量的引用共享?
问题重现
你遇到的问题我之前也碰见过!copy.deepcopy()并不能真正创建一个独立的类副本——它只是对类对象做了浅层处理,类的命名空间(包括类变量)仍然和原类共享引用。比如你的测试代码:
import copy class TestEvent(object): value = None clsOne = TestEvent clsTwo = copy.deepcopy(TestEvent) clsOne.value = "hello motto" print(clsTwo.value) # 输出 "hello motto",类变量完全共享
解决方案:手动构建独立新类
要创建完全独立的类副本,我们需要手动构建一个全新的类对象,复制原类的基类和属性,但使用独立的命名空间。这里有两种简单可靠的方法:
方法1:使用type()动态创建类
type()是Python中所有类的默认元类,我们可以直接用它生成新类,把原类的属性复制到独立字典中:
def copy_class(cls): # 参数分别为:新类名、基类元组、独立的属性字典 return type(cls.__name__, cls.__bases__, dict(cls.__dict__)) # 测试验证 class TestEvent(object): value = None clsOne = TestEvent clsTwo = copy_class(TestEvent) clsOne.value = "hello motto" print(clsOne.value) # 输出 "hello motto" print(clsTwo.value) # 输出 None,完全独立!
方法2:使用types.new_class()(更严谨)
如果你的类有自定义元类或者特殊属性(比如__slots__),可以用types模块的new_class()来更规范地创建新类:
import types def copy_class(cls): # 复制原类属性,移除会干扰新类创建的特殊属性 namespace = dict(cls.__dict__) namespace.pop('__dict__', None) namespace.pop('__weakref__', None) # 创建新类并更新独立命名空间 return types.new_class( cls.__name__, cls.__bases__, {}, # 元类关键字参数(如有需要可添加) lambda ns: ns.update(namespace) )
为什么copy.deepcopy()不行?
Python的copy模块在处理类对象时,并不会重新构建类的完整结构。类是元类(默认是type)的实例,deepcopy对元类实例的处理逻辑是复用原有的类属性,而非创建全新的命名空间。所以类变量仍然会共享原类的引用,导致修改互相影响。
内容的提问来源于stack exchange,提问作者Kirk Douglas Jr
相关产品推荐
相关产品推荐

