Reputation: 6548
I am trying to understand one observation.
I have an application that loads various Canvas
classes which a user can later work with. These classes are located in several files.
For example.
canvas/
bw.py
colored.py
oil.py
I import, instantiate and copy these objects like this:
canvas_files = os.listdir('images')
imported_canvs = []
for canv in canvas_files:
canv = __import__(canv.split('.')[0], fromlist=['Canvas'])
try:
new_canv = canv.Canvas()
new_canv_copy = copy.copy(new_canv)
imported_canvs.append(new_canv_copy)
except AttributeError as ex:
pass
Afterwards, a user works with each Canvas
object from imported_canvs
list. However, when I import and instantiate these objects twice (run the for
loop again) I can see id(new_canv_copy)
is the same as previously imported and instantiated ones.
This would not be a problem unless that each Canvas
has settings which should be unique for each instance and this is not currently happening. Whenever a user changes the settings in one Canvas
they are automatically changed in the copied one.
Why is this happening and what am I doing wrong?
Upvotes: 1
Views: 60
Reputation: 6341
Regarding your note on running the for
loop several times ad getting the same id
's... It might not be the problem with copy.copy
, as it copies top-level object and id
's for top-level mutable objects should differ, but id
's for inner mutable objects will stay the same, unlike copy.deepcopy
where all mutable objects id
's should differ.
Probably it's the issue with the __import__
itself...
When you import a module in Python, it's imported only once. So when you issue the first import of the module 'some_module_a.py' it is imported, and then, when you issue a second import of the same module 'some_module_a.py' it's not imported again, but the reference to the already imported module is reused/returned.
So if you need to re-import the same module more than once, import it for the first time and then use importlib.reload
to have it trully imported again.
Upvotes: 1
Reputation: 96959
Using just copy.copy()
creates a shallow copy. You probably want to use deep copy when copying objects using copy.deepcopy()
.
You can read in detail what's the difference here: https://docs.python.org/2/library/copy.html
I don't know what canv.Canvas()
does inside so it's hard to tell what's going on when you run the same code twice when I can't try it by myself.
Upvotes: 1
Reputation: 31183
copy.copy
performs a shallow copy, meaning any objects will point to existing objects. If you want the objects inside it also to be cloned, you need to use copy.deepcopy
.
Upvotes: 0