Lately I've been writing a lot of code involving the creation of new objects, and I quickly come to find that Python almost always creates a reference to an object instead of a new object. I understand the importance of conserving memory usage, but in this instance I actually need a true copy.

My problem is that I have yet to find anything in Python that can quickly generate a true copy of all objects. I am aware of the copy module, but it will not copy certain objects I need to copy. I have had some success experimenting with creating a new, blank object and initializing it to be the same as another object, but this is a sometimes lengthy and complex process. My question is if there is a feature that allows programmers to easily copy objects using a simple assignment.

Python is a good language, but it seems like its lacking an intuitive way to copy objects.

Edited 6 Years Ago by lrh9: n/a

Only mutable objects are passed by reference, since they can change internally. So, assignment will not create a true copy, just an alias. The module copy handles many mutable objects. However there are more complex objects than cannot be easily copied. For instance a recursive situation.

as someone here once showed me:

x = [1, 2, 3]

y = x[:] # y is now a copy of x

That only works on lists, but thanks for pointing that out.

Only mutable objects are passed by reference, since they can change internally. So, assignment will not create a true copy, just an alias. The module copy handles many mutable objects. However there are more complex objects than cannot be easily copied. For instance a recursive situation.

Right. The copy module itself lists some of the objects it doesn't copy. I don't know why it would be so hard to create a set of functions and classes to handle the copy of objects. Almost any object or data type in Python is in fact a first class object.

as someone here once showed me:

x = [1, 2, 3]

y = x[:] # y is now a copy of x

This will not work for nested lists.
Example

x = [1, 2, [3, 4, 5]]

y = x[:]

x[1] = 99
print( x )  # [1, 99, [3, 4, 5]]
print( y )  # [1, 2, [3, 4, 5]]    okay

x[2][1] = 33
print( x )  # [1, 99, [3, 33, 5]]
print( y )  # [1, 2, [3, 33, 5]]   oh no

This will not work for nested lists.
Example

No problem,kidding this one was not so easy.
Search and think,did find a soultion.

def unshared_copy(inList):
    if isinstance(inList, list):
        return list( map(unshared_copy, inList) )
    return inList

inlist = [1, 2, [3, 4, 5]]
copy_list = unshared_copy(inlist)

print inlist
print copy_list
print
print id(inlist)
print id(copy_list)
print inlist == copy_list
print
inlist[1] = 99
print inlist
print copy_list
print
inlist[2][1] = 33
print inlist
print copy_list
'''
[1, 2, [3, 4, 5]]
[1, 2, [3, 4, 5]]

15060344
15060464
True

[1, 99, [3, 4, 5]]
[1, 2, [3, 4, 5]]

[1, 99, [3, 33, 5]]
[1, 2, [3, 4, 5]]
'''

Have you looked at or tried if deepcopy works for you irh9?
http://www.doughellmann.com/PyMOTW/copy/index.html

Edited 6 Years Ago by snippsat: n/a

I am aware of the copy module, but it will not copy certain objects I need to copy.

See my initial post.

This will not work for nested lists.
Example

x = [1, 2, [3, 4, 5]]

y = x[:]

x[1] = 99
print( x )  # [1, 99, [3, 4, 5]]
print( y )  # [1, 2, [3, 4, 5]]    okay

x[2][1] = 33
print( x )  # [1, 99, [3, 33, 5]]
print( y )  # [1, 2, [3, 33, 5]]   oh no

This is an example where copy.deepcopy() will work just fine.

Can you give an example of what those certain objects are?

So far the only objects I've been interested in generating true copies of are module objects and function objects.

I learned how to create a module object, so I was going to learn how to create a custom importer. I'm probably still going to do this because it will allow me to incorporate some additional features.

However, when I attempted to create a true copy of a function object, it failed miserably and was too complex for me to figure out. deepcopy claims to be able to copy function objects, but when I used it, I did not get the desired behavior.

This article has been dead for over six months. Start a new discussion instead.