gpt4 book ai didi

python - 如何将一个 Python 对象的所有属性复制到另一个对象?

转载 作者:太空狗 更新时间:2023-10-29 22:22:18 24 4
gpt4 key购买 nike

我有两个类,其中一个继承自另一个:

class DaParent(object):
name = ''
number = 0

class DaChild(DaParent):
additional = ''

我现在创建一个 Parent 并更改属性:

parent = DaParent()
parent.name = 'papa'
parent.number = 123

从这一点开始,我想创建一个子对象,我想在其中复制父对象的所有属性。我当然可以这样做:

child = DaChild()
child.name = parent.name
child.number = parent.number

问题是,在开发过程中,这个类会增长到具有相当多的属性,我不想经常更改将属性手动复制到子类中。

有没有办法自动接管父对象的属性到新的子对象中?欢迎所有提示!

[编辑]只是为了解释我为什么要这样做。我用 Peewee ORM与我的数据库交互。我现在想修改一个表(这意味着如果记录得到更新,我想保留所有以前的版本)。我打算这样做的方法是创建一个 Person 类和一个继承自 Person 类的 PersonRevision 类。然后我覆盖 peewee save() method不仅要保存 Person 对象,还要将所有属性复制到 PersonRevision 对象中并保存。因为我实际上永远不会直接与 PersonRevision 类交互,所以我不需要阴影或任何花哨的东西。我只想复制属性并调用对象的 save() 方法。

最佳答案

显而易见的解决方案是使用组合/委托(delegate)而不是继承:

class Parent(object):
def __init__(self, name, number):
self.name = name
self.number = number


class Child(object):
def __init__(self, parent, other):
self.parent = parent
self.other = other

def __getattr__(self, name):
try:
return getattr(self.parent, name)
except AttributeError, e:
raise AttributeError("Child' object has no attribute '%s'" % name)

p = Parent("Foo", 42)
c = Child(p, "parrot")
print c.name, c.number, c.other
p.name = "Bar"
print c.name, c.number, c.other

这当然是假设您真的不想要“副本”而是“引用”。如果你真的想要一个副本,它也是可能的,但对于可变类型它可能会变得棘手:

import copy

class Parent(object):
def __init__(self, name, number):
self.name = name
self.number = number


class Child(object):
def __init__(self, parent, other):
# only copy instance attributes from parents
# and make a deepcopy to avoid unwanted side-effects
for k, v in parent.__dict__.items():
self.__dict__[k] = copy.deepcopy(v)
self.other = other

如果这些解决方案都不符合您的需求,请解释您的真实用例 - 您可能遇到 XY 问题。

[编辑] 确实接近 XY 问题。真正的问题是:“如何将 peewee.Model 的字段复制到另一个 peewee.Modelpeewee 使用描述符(peewee.FieldDescriptor) 来控制对模型字段的访问,并将字段名称和定义存储在模型的 _meta.fields 字典中,因此最简单的解决方案是迭代源模型的 _meta.fields 键并使用 getattr/setattr:

class RevisionMixin(object):
@classmethod
def copy(cls, source, **kw):
instance = cls(**kw)
for name in source._meta.fields:
value = getattr(source, name)
setattr(instance, name, value)
return instance

class Person(peewee.Model):
# fields defintions here


class PersonRevision(Person, RevisionMixin):
# additional fields definitions here


p = Person(name="foo", number=42)
r = PersonRevision.copy(p, whatelse="parrot")

注意:未经测试的代码,从未使用过 peewee,可能还有更好的事情要做...

关于python - 如何将一个 Python 对象的所有属性复制到另一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26467564/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com