顯而易見的解決方案是使用合成/委託,而不是傳承的:
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