close

How to copy a class instance in python?

Hello Guys, How are you all? Hope You all Are Fine. Today We Are Going To learn about How to copy a class instance in python in Python. So Here I am Explain to you all the possible Methods here.

Without wasting your time, Let’s start This Article.

Table of Contents

How to copy a class instance in python?

  1. How to copy a class instance in python?

    1) I have a set of default arguments for class C which I call argsC. 2) All objects in C can be initialized with empty arguments.

  2. copy a class instance in python

    1) I have a set of default arguments for class C which I call argsC. 2) All objects in C can be initialized with empty arguments.

Method 1

Yes you can make a copy of class instance using deepcopy:

from copy import deepcopy

c = C(4,5,'r'=2)
d = deepcopy(c)

This creates the copy of class instance ‘c’ in ‘d’ .

Method 2

I have mostly figured it out. The only problem which I cannot overcome is knowing an acceptable set of initialization arguments (arguments for __init__) for all classes. So I have to make the following two assumtions:

1) I have a set of default arguments for class C which I call argsC. 2) All objects in C can be initialized with empty arguments.

In which case I can First: Initialize a new instance of the class C from it’s instance which I want to copy c:

c_copy = c.__class__(**argsC)

Second: Go through all the attributes of c and set the attributes c_copy to be a copy of the attributes of c

for att in c.__dict__:
    setattr(c_copy, att, object_copy(getattr(c,att)))

where object_copy is a recursive application of the function we are building.

Last: Delete all attributes in c_copy but not in c:

for att in c_copy.__dict__:
    if not hasattr(c, att):
        delattr(c_copy, att)

Putting this all together we have:

import copy

def object_copy(instance, init_args=None):
    if init_args:
        new_obj = instance.__class__(**init_args)
    else:
        new_obj = instance.__class__()
    if hasattr(instance, '__dict__'):
        for k in instance.__dict__ :
            try:
                attr_copy = copy.deepcopy(getattr(instance, k))
            except Exception as e:
                attr_copy = object_copy(getattr(instance, k))
            setattr(new_obj, k, attr_copy)

        new_attrs = list(new_obj.__dict__.keys())
        for k in new_attrs:
            if not hasattr(instance, k):
                delattr(new_obj, k)
        return new_obj
    else:
        return instance

So putting it all together we have:

argsC = {'a':1, 'b':1}
c = C(4,5,r=[[1],2,3])
c.a = 11
del c.b
c_copy = object_copy(c, argsC)
c.__dict__

{‘a’: 11, ‘r’: [[1], 2, 3]}

c_copy.__dict__

{‘a’: 11, ‘r’: [[1], 2, 3]}

c.__dict__

{‘a’: 11, ‘r’: [[1, 33], 2, 3]}

c_copy.__dict__

{‘a’: 11, ‘r’: [[1], 2, 3]}

Which is the desired outcome. It uses deepcopy if it can, but for the cases where it would raise an exception, it can do without.

Summery

It’s all About this issue. Hope all Methods helped you a lot. Comment below Your thoughts and your queries. Also, Comment below which Method worked for you? Thank You.

Also, Read