kra*_*r65 7 python oop inheritance class object
我有两个类,其中一个继承自另一个类:
class DaParent(object):
name = ''
number = 0
class DaChild(DaParent):
additional = ''
Run Code Online (Sandbox Code Playgroud)
我现在创建一个Parent并更改属性:
parent = DaParent()
parent.name = 'papa'
parent.number = 123
Run Code Online (Sandbox Code Playgroud)
从这一点来说,我想创建一个Child,我想在其中复制父项的所有属性.我当然可以这样做:
child = DaChild()
child.name = parent.name
child.number = parent.number
Run Code Online (Sandbox Code Playgroud)
问题在于,在开发过程中,这个类将变得具有相当多的属性,并且我不经常想要将属性的手动复制更改为子项.
有没有办法自动将父对象的属性接管到新的子对象中?欢迎所有提示!
[编辑]只是为了解释为什么我想这样做.我使用Peewee ORM与我的DB进行交互.我现在想修改一个表(意思是如果记录得到更新,我想保留所有以前的版本).我打算这样做的方法是通过例如创建一个继承自该类的Person类和类.然后我重写peewee save()方法,不仅保存对象,还将所有属性复制到对象中并保存.因为我永远不会直接与班级互动,所以我不需要阴影或任何花哨的东西.我只想复制属性并调用对象的方法.PersonRevisionPersonPersonPersonRevisionPersonRevisionsave()
显而易见的解决方案是使用组合/委托而不是继承:
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
Run Code Online (Sandbox Code Playgroud)
这当然是假设你真的不想要"副本"而是"引用".如果你真的想要一个副本,它也是可能的,但它可能会变得棘手的可变类型:
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
Run Code Online (Sandbox Code Playgroud)
如果这些解决方案都不符合您的需求,请解释您的实际用例 - 您可能遇到XY问题.
[编辑]确实接近XY问题.真正的问题是:"如何将peewee.Model字段复制到另一个字段中peewee.Model.peewee使用descriptors(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")
Run Code Online (Sandbox Code Playgroud)
NB:未经测试的代码,从未使用过peewee,有可能做得更好......
| 归档时间: |
|
| 查看次数: |
5447 次 |
| 最近记录: |