显而易见的解决方案是使用合成/委托,而不是传承的:
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.Model
。peewee
使用描述符(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
,有可能是更好的东西做...
你采取行动真的希望这些是* class *,而不是* instance *属性? – jonrsharpe 2014-10-20 14:05:03
@jonrsharpe - 据我所知他们需要是实例属性,所以属性的对象,而不是类本身。 – kramer65 2014-10-20 14:10:19
这是**不是**你现在拥有的 - 在'class'内定义的属性,但在实例方法'def'之外定义的属性是* class attributes *。 – jonrsharpe 2014-10-20 14:21:26