I have to access a set of large and not pickable python objects from many processes. Therefore, I would like to ensure that these objects are not copied completely.
According to comments in this and this post, objects are not copied (on unix systems) unless they are changed. However, referencing an object will change its reference count, which in turn will then be copied.
Is this correct so far? Since my concern is due to the size of my large objects, I do not have a problem, if small parts of these objects are copied.
To ensure that I understood everything correctly and that nothing unexpected happens, I implemented a small test program:
from multiprocessing import Pool
def f(arg):
print(l, id(l), object.__repr__(l))
l[arg] = -1
print(l, id(l), object.__repr__(l))
def test(n):
global l
l = list(range(n))
with Pool() as pool:
pool.map(f, range(n))
print(l, id(l), object.__repr__(l))
if __name__ == '__main__':
test(5)
In the first line of f
, I would expect id(l)
to return the same number in all function calls, since the list is not changed before the id
check.
On the other hand, in the third line of f
, id(l)
should return a different number in each method call, since the list is changed in the second line.
However, the program output puzzles me.
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[-1, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, -1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, -1, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, -1, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, -1] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488
The id is the same in all calls and lines of f
. This is the case even though the list remains unchanged at the end (as expected), which implies that the list has been copied.
How can I see whether an object has been copied or not?