Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a decent way of creating a copy constructor in python?

I realize questions quite similar to this have been asked, though not exactly this way.

I'd like to have an optional argument for the constructor of my class that, if it is an instance of my class, will be copied. For example, something like (I know this code does not work!):

class Foo(object):
    def __init__(self, foo=None):
        self.x = None
        self.y = None
        self.z = None

        if foo is not None and isinstance(foo, Foo):
            self = copy.deepcopy(foo)

a = Foo()
a.x = 1
a.y = 2
a.z = 3

b = Foo(a)
print b.x
print b.y
print b.z

I know there are a few practical solutions to this. I could set each attribute of self according to the value of foo's corresponding attribute, but this would be really annoying because my class has many, many attributes. Or I could simply use do:

b = copy.deepcopy(a)

...But I'd rather not if that is possible. I'm also hoping to avoid overriding __new__.

Is there really no decent way at all in python to create a copy constructor?

like image 304
carmenism Avatar asked May 17 '12 17:05

carmenism


People also ask

Is there any copy constructor in Python?

you can control copying in much the same way as you control pickle. deepcopy works well for doing this external to the class definition. But @Zitrax wants to do this within his class definition so that the new instance inherits the attributes (data) from an object of a different (parent) type (class).

Does copy constructor make shallow copy or deep copy?

The default copy constructor and default assignment operators do shallow copies, which is fine for classes that contain no dynamically allocated variables. Classes with dynamically allocated variables need to have a copy constructor and assignment operator that do a deep copy.

Does Python do deep copy?

Understand how copying works in Python with helpful examples Image by the author. In Python, a shallow copy is a “one-level-deep” copy. The copied object contains references to the child objects of the original object. A deep copy is completely independent of the original object.

Can there be multiple copy constructor?

A class can have multiple copy constructors, e.g. both T::T(const T&) and T::T(T&). If some user-defined copy constructors are present, the user may still force the generation of the implicitly declared copy constructor with the keyword default .


1 Answers

I think this is the most pythonic way of doing it - a copy factory method.

import copy

class Foo(object):
    def __init__(self):
        self.x = None
        self.y = None
        self.z = None
    def copy(self):
        return copy.deepcopy(self)

a = Foo()
a.x = 1
a.y = 2
a.z = 3

b = a.copy()
print b.x
print b.y
print b.z

This is fairly common in python basic types (eg dict.copy). It is not a copy constructor, but I don't think that is a very pythonic concept!

like image 100
Nick Craig-Wood Avatar answered Oct 06 '22 09:10

Nick Craig-Wood