deepcopy有问题吗?

2024-05-19 09:48:42 发布

您现在位置:Python中文网/ 问答频道 /正文

来源

from copy import deepcopy

class Field(object):
    def __init__(self):
        self.errors = []

class BaseForm(object):
    pass

class MetaForm(type):
    def __new__(cls, name, bases, attrs):
        attrs['fields'] = dict([(name, deepcopy(attrs.pop(name))) for name, obj in attrs.items() if isinstance(obj, Field)])
        return type.__new__(cls, name, bases, attrs)

class Form(BaseForm):
    __metaclass__ = MetaForm

class MyForm(Form):
    field1 = Field()

f1 = MyForm()
f1.fields['field1'].errors += ['error msg']

f2 = MyForm()
print f2.fields['field1'].errors

输出

^{pr2}$

问题

为什么它会输出这个呢?我想我在修改错误列表之前克隆了它,它们不应该同时引用同一个列表?在


Tags: nameselffieldfieldsobjectdeftypeattrs
2条回答

通过在metaclass中设置dictfields,您正在创建一个class属性。在

您定义的__new__方法在类创建时只运行一次。在

更新

您应该像您一样操作__new__中的attrs,但将其命名为_fields。然后创建一个__init__方法,将deepcopy执行到名为fieldsattribute中。在

更明确的解决方案:

from copy import deepcopy

class Field(object):
    def __init__(self):
        self.errors = []

class BaseForm(object):
    def __init__(self):
        self.fields = deepcopy(self.fields)

class MetaForm(type):
    def __new__(cls, name, bases, attrs):
        attrs['fields'] = dict([(name, attrs.pop(name)) for name, obj in attrs.items() if isinstance(obj, Field)])
        return type.__new__(cls, name, bases, attrs)

class Form(BaseForm):
    __metaclass__ = MetaForm

class MyForm(Form):
    field1 = Field()

f1 = MyForm()
f1.fields['field1'].errors += ['error msg']

f2 = MyForm()
print f2.fields['field1'].errors

只需将deepcopy移到BaseForm.__init__中,实际上每次实例化一个MyForm时,都会被调用。在

相关问题 更多 >

    热门问题