To get a fully independent copy of an object you can use the copy.deepcopy() function.

For more details about shallow and deep copying please refer to the other answers to this question and the nice explanation in this answer to a related question.

Answer from Sven Marnach on Stack Overflow
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ copy.html
copy โ€” Shallow and deep copy operations
... This module does not copy types like module, method, stack trace, stack frame, file, socket, window, or any similar types. It does โ€œcopyโ€ functions and classes (shallow and deeply), by returning the original object unchanged; this is ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ copy-python-deep-copy-shallow-copy
Deep Copy and Shallow Copy in Python - GeeksforGeeks
A deep copy creates a new compound object before inserting copies of the items found in the original into it in a recursive manner. It will first construct a new collection object and then recursively populate it with copies of the child objects ...
Published: February 5, 2026
Discussions

oop - How can I create a copy of an object in Python? - Stack Overflow
Possible use cases: making a shallow copy of a standard Python container class. ... That's neat and all, but does not answer the question as your copy function fails for custom classes and the question was about objects. 2018-02-21T12:55:08.977Z+00:00 ... @JaredSmith, it was not stated that the question was about all objects. It was not even clear if it was about deep ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Should I Use Deepcopy for Class Initializers?
In languages which embrace mutability, what you are trying to do is contrary to expectations. I.e. in such a language, you'd expect that the function implementation "owns" its arguments, and is allowed to modify them whichever way it likes. For example, that's why sort() in Python changes the list instead of returning a new one. If the users of your class want to keep their list intact, it's on them to make a copy. The rationale for this is similar to the one about manual memory management vs garbage collector. In languages which try to prevent unnecessary mutation, there are special mechanisms in language runtime that allow it to optimize copying behind the scenes. In languages w/o such ability, the runtime is simpler (it doesn't know how to optimize copying) at the expense of the user of such language having to decide on a case-by-case basis whether they want a copy or not. More on reddit.com
๐ŸŒ r/learnpython
4
4
October 13, 2021
Python - DeepCopy of custom class instance
Hi, Iโ€™m trying to make a deepCopy of a custom python class instance, but it is miserably failing. I suspect that Iโ€™m missing some basic theory here. Any help on understanding why is happening this? thanks! More on discourse.mcneel.com
๐ŸŒ discourse.mcneel.com
8
0
April 6, 2020
How to copy a Python class instance if deepcopy() does not work? - Stack Overflow
I would like to make a copy of a class instance in python. I tried copy.deepcopy but I get the error message: More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
Python for the Lab
pythonforthelab.com โ€บ blog โ€บ deep-and-shallow-copies-of-objects
Deep and Shallow Copies of Objects | Python For The Lab
It is very important to point out that, if are worried about copying and deep copying of custom objects, you should understand what are mutable and immutable objects in Python, and what are hashable objects. When you have immutable data types, such as an integer or a string, all the discussion above doesn't work. If you change an immutable attribute in a class, that attribute in deep-copied objects will not change.
๐ŸŒ
Python Module of the Week
pymotw.com โ€บ 2 โ€บ copy
copy โ€“ Duplicate objects - Python Module of the Week
Now available for Python 3! Buy the book! ... The copy module includes 2 functions, copy() and deepcopy(), for duplicating existing objects. The shallow copy created by copy() is a new container populated with references to the contents of the original object.
๐ŸŒ
The Python Coding Book
thepythoncodingbook.com โ€บ home โ€บ blog โ€บ shallow and deep copy in python and how to use __copy__()
Shallow and Deep Copy in Python and How to Use __copy__()
November 12, 2023 - In more complex classes, you may want to define both __copy__() and __deepcopy__() if you want to distinguish between shallow and deep copy in your Python program.
Top answer
1 of 4
346

To get a fully independent copy of an object you can use the copy.deepcopy() function.

For more details about shallow and deep copying please refer to the other answers to this question and the nice explanation in this answer to a related question.

2 of 4
177

How can I create a copy of an object in Python?

So, if I change values of the fields of the new object, the old object should not be affected by that.

You mean a mutable object then.

In Python 3, lists get a copy method (in 2, you'd use a slice to make a copy):

>>> a_list = list('abc')
>>> a_copy_of_a_list = a_list.copy()
>>> a_copy_of_a_list is a_list
False
>>> a_copy_of_a_list == a_list
True

Shallow Copies

Shallow copies are just copies of the outermost container.

list.copy is a shallow copy:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

You don't get a copy of the interior objects. They're the same object - so when they're mutated, the change shows up in both containers.

Deep copies

Deep copies are recursive copies of each interior object.

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

Changes are not reflected in the original, only in the copy.

Immutable objects

Immutable objects do not usually need to be copied. In fact, if you try to, Python will just give you the original object:

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'copy'

Tuples don't even have a copy method, so let's try it with a slice:

>>> tuple_copy_attempt = a_tuple[:]

But we see it's the same object:

>>> tuple_copy_attempt is a_tuple
True

Similarly for strings:

>>> s = 'abc'
>>> s0 = s[:]
>>> s == s0
True
>>> s is s0
True

and for frozensets, even though they have a copy method:

>>> a_frozenset = frozenset('abc')
>>> frozenset_copy_attempt = a_frozenset.copy()
>>> frozenset_copy_attempt is a_frozenset
True

When to copy immutable objects

Immutable objects should be copied if you need a mutable interior object copied.

>>> tuple_of_list = [],
>>> copy_of_tuple_of_list = tuple_of_list[:]
>>> copy_of_tuple_of_list[0].append('a')
>>> copy_of_tuple_of_list
(['a'],)
>>> tuple_of_list
(['a'],)
>>> deepcopy_of_tuple_of_list = copy.deepcopy(tuple_of_list)
>>> deepcopy_of_tuple_of_list[0].append('b')
>>> deepcopy_of_tuple_of_list
(['a', 'b'],)
>>> tuple_of_list
(['a'],)

As we can see, when the interior object of the copy is mutated, the original does not change.

Custom Objects

Custom objects usually store data in a __dict__ attribute or in __slots__ (a tuple-like memory structure.)

To make a copyable object, define __copy__ (for shallow copies) and/or __deepcopy__ (for deep copies).

from copy import copy, deepcopy

class Copyable:
    __slots__ = 'a', '__dict__'
    def __init__(self, a, b):
        self.a, self.b = a, b
    def __copy__(self):
        return type(self)(self.a, self.b)
    def __deepcopy__(self, memo): # memo is a dict of id's to copies
        id_self = id(self)        # memoization avoids unnecesary recursion
        _copy = memo.get(id_self)
        if _copy is None:
            _copy = type(self)(
                deepcopy(self.a, memo), 
                deepcopy(self.b, memo))
            memo[id_self] = _copy 
        return _copy

Note that deepcopy keeps a memoization dictionary of id(original) (or identity numbers) to copies. To enjoy good behavior with recursive data structures, make sure you haven't already made a copy, and if you have, return that.

So let's make an object:

>>> c1 = Copyable(1, [2])

And copy makes a shallow copy:

>>> c2 = copy(c1)
>>> c1 is c2
False
>>> c2.b.append(3)
>>> c1.b
[2, 3]

And deepcopy now makes a deep copy:

>>> c3 = deepcopy(c1)
>>> c3.b.append(4)
>>> c1.b
[2, 3]
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ should i use deepcopy for class initializers?
r/learnpython on Reddit: Should I Use Deepcopy for Class Initializers?
October 13, 2021 -
import copy

class Foo:
    def __init__(self, my_list):
        self.my_list = copy.deepcopy(my_list)

bar = Foo([0, 1, 2])

I always deepcopy objects that isn't deepcopied by default when initializing a function like above. Is this a memory efficient practice, or is it useless?

Find elsewhere
๐ŸŒ
iO Flood
ioflood.com โ€บ blog โ€บ python-deepcopy
Python Deepcopy Syntax and Usage Guide (With Examples)
February 5, 2024 - Pythonโ€™s deepcopy will use these methods if they are present to copy the object, and this might not always result in the required behavior. ... import copy class Foo: def __init__(self, foo): self.foo = foo def __deepcopy__(self, memo): return Foo(self.foo + "_deepcopy") foo_instance = Foo("test") foo_deepcopy = copy.deepcopy(foo_instance) print('Original:', foo_instance.foo) print('Deep Copy:', foo_deepcopy.foo)
๐ŸŒ
Real Python
realpython.com โ€บ copying-python-objects
How to Copy Objects in Python: Shallow vs Deep Copy Explained โ€“ Real Python
1 week ago - Deep Copy: When you need a deep copy of an object, as no other built-in mechanism in Python provides this capability. Replace: If you want to shallowly copy a compatible typeโ€”for example, a named tuple, data class, or date and timeโ€”with ...
๐ŸŒ
McNeel Forum
discourse.mcneel.com โ€บ rhino developer
Python - DeepCopy of custom class instance - Rhino Developer - McNeel Forum
April 6, 2020 - Hi, Iโ€™m trying to make a deepCopy of a custom python class instance, but it is miserably failing. I suspect that Iโ€™m missing some basic theory here. Any help on understanding why is happening this? thanks!
๐ŸŒ
Programiz
programiz.com โ€บ python-programming โ€บ shallow-deep-copy
Python Shallow Copy and Deep Copy (With Examples)
The deep copy creates independent copy of original object and all its nested objects.
๐ŸŒ
Peterbe.com
peterbe.com โ€บ plog โ€บ must__deepcopy__
When to __deepcopy__ classes in Python - Peterbe.com
March 14, 2012 - If you do that, you loose the ability to use copy.deepcopy since the class has now been slightly "abused". >>> a = ORM(data={'name': 'Something'}) >>> a.data['name'] 'Something' >>> b = copy.deepcopy(a) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/Cellar/python/2.7.2/lib/python2.7/copy.py", line 172, in deepcopy copier = getattr(x, "__deepcopy__", None) File "<stdin>", line 3, in __getattr__ KeyError: '__deepcopy__'
Top answer
1 of 2
3

Your first question:

As pointed out by @Blckknght in the comments, when you pass a class-definition object to copy.deepcopy(), you run into a behavior of deepcopy() that is surprising / quirky, though intentional -- instead of making a deep copy of the class-definition object, deepcopy() merely returns a reference to the same class-definition object.

To verify this,

print ("b is:", b)
b_instance = b()
print ("b is Test ?:", (b is Test))

gives:

b is: <class '__main__.Test'>
b is Test ?: True             # deepcopy() hasn't made a copy at all !

Here's what the doc says regarding deepcopy() for class-definition objects:

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, array, or any similar types. It does โ€œcopyโ€ functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the pickle module.

So, when you do

b.a = 1

you're still modifying the class variable of the class Test.

Your second question:

When you do

c = type('Test2', (Test,), {'a': 2})

you are creating a new type called Test2, with its own class variable called a, and having Test as its superclass.

Now Test2.a and Test.a are two different class variables, defined in two different classes, and can take values independently of each other. One is a class variable called a in the superclass Test, the other is a class variable with the same name a in the subclass Test2.

That is why c.a will give 2 (the value to which you initialized it), and Test.a will continue to give 1

2 of 2
0

You copied the class definition and not the instance itself.

You should be doing something like this instead:

import copy

class Test:
    def __init__(self,a):
        self.a = a

test1 = Test(0)
test2 = copy.deepcopy(test1)

print("Original:")
print("Test 1: " + str(test1.a)) #0
print("Test 2: " + str(test2.a)) #0

print("Modify test 2 to 10")
test2.a = 10
print("Test 1: " + str(test1.a)) #0
print("Test 2: " + str(test2.a)) #10

Original:

Test 1: 0

Test 2: 0

Modify test 2 to 10

Test 1: 0

Test 2: 10

๐ŸŒ
Stack Abuse
stackabuse.com โ€บ python-deep-and-shallow-copy-object
Python: Deep and Shallow Copy Object
September 27, 2021 - We also learned that we can use the copy() method of the copy module to create a shallow copy, and the deepcopy() method to create a deep copy of the compound objects. ... Get tutorials, guides, and dev jobs in your inbox. No spam ever. Unsubscribe at any time.
Top answer
1 of 10
149

Putting together Alex Martelli's answer and Rob Young's comment you get the following code:

from copy import copy, deepcopy

class A:
    def __init__(self):
        print('init')
        self.v = 10
        self.z = [2, 3, 4]

    def __copy__(self):
        cls = self.__class__
        result = cls.__new__(cls)
        result.__dict__.update(self.__dict__)
        return result
    
    def __deepcopy__(self, memo):
        cls = self.__class__
        result = cls.__new__(cls)
        memo[id(self)] = result
        for k, v in self.__dict__.items():
            setattr(result, k, deepcopy(v, memo))
        return result
            
a = A()
a.v = 11
b1, b2 = copy(a), deepcopy(a)
a.v = 12
a.z.append(5)
print(b1.v, b1.z)
print(b2.v, b2.z)

prints

init
11 [2, 3, 4, 5]
11 [2, 3, 4]

here __deepcopy__ fills in the memo dict to avoid excess copying in case the object itself is referenced from its member.

2 of 10
97

The recommendations for customizing are at the very end of the docs page:

Classes can use the same interfaces to control copying that they use to control pickling. See the description of module pickle for information on these methods. The copy module does not use the copy_reg registration module.

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__(). The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. If the __deepcopy__() implementation needs to make a deep copy of a component, it should call the deepcopy() function with the component as first argument and the memo dictionary as second argument.

Since you appear not to care about pickling customization, defining __copy__ and __deepcopy__ definitely seems like the right way to go for you.

Specifically, __copy__ (the shallow copy) is pretty easy in your case...:

def __copy__(self):
  newone = type(self)()
  newone.__dict__.update(self.__dict__)
  return newone

__deepcopy__ would be similar (accepting a memo arg too) but before the return it would have to call self.foo = deepcopy(self.foo, memo) for any attribute self.foo that needs deep copying (essentially attributes that are containers -- lists, dicts, non-primitive objects which hold other stuff through their __dict__s).

๐ŸŒ
Medium
medium.com โ€บ @rinu.gour123 โ€บ copy-in-python-python-deep-copy-and-shallow-copy-96ed1a42188
Copy in Python โ€” Python Deep Copy and Shallow Copy | by Rinu Gour | Medium
February 18, 2019 - It is possible that a deep copy may copy too much. ... Keeps a memo dictionary of objects is copied during the current copying pass. Allows user-defined classes to override the copying operation or the copied component set.
๐ŸŒ
Note.nkmk.me
note.nkmk.me โ€บ home โ€บ python
Shallow and Deep Copy in Python: copy(), deepcopy() | note.nkmk.me
May 13, 2023 - A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original. copy โ€” Shallow and deep copy operations โ€” Python 3.11.3 documentation