I've got two classes, of which one inherits from the other:
class DaParent(object):
name = ''
number = 0
class DaChild(DaParent):
additional = ''
I now create a Parent and change the attributes:
parent = DaParent()
parent.name = 'papa'
parent.number = 123
And from this point, I want to create a Child in which I want to copy all the attributes from the parent. I can of course do this like so:
child = DaChild()
child.name = parent.name
child.number = parent.number
The thing is that while developing, this class will grow to have a fairly large number of attributes, and I don't constantly want to change the manual copying of the attributes into the child.
Is there a way to automatically take over the attributes of the parent object into a new child object? All tips are welcome!
[EDIT]
Just to explain the WHY I want to do this. I use the Peewee ORM to interact with my DB. I now want to revision a table (meaning if a record gets updated, I want keep all previous versions). The way I intent to do that is by for example creating a Person
class and a PersonRevision
class which inherits from the Person
class. I then override the peewee save() method to not only save the Person
object, but also copy all attributes into a PersonRevision
object and save that as well. Since I will never actually directly interact with the PersonRevision
class I don't need shadowing or any fancy stuff. I just want to copy the attributes and call the object its save()
method.
Python – clone() function in wand library clone() function makes an exact copy of the original image. One can use this clone image to manipulate without affecting the original image. clone() is one of the most important function because it helps in safe manipulation of image.
A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
The obvious solution is to use composition/delegation instead of inheritence:
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
This is of course assuming that you dont really want "copies" but "references to". If you really want a copy it's also possible but it can get tricky with mutable types:
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
If none of these solutions fit your needs, please explain your real use case - you may have an XY problem.
[edit] Bordering on a XY problem, indeed. The real question is: "How do I copy a peewee.Model
's fields into another peewee.Model
. peewee
uses descriptors (peewee.FieldDescriptor
) to control access to model's fields, and store the fields names and definitions in the model's _meta.fields
dict, so the simplest solution is to iterate on the source model's _meta.fields
keys and use 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")
NB : untested code, never used peewee
, there's possibly something better to do...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With