I have a function that I want to use to manipulate an input parameter, however, in the process I must copy the input parameter. I do not want to return the modified object (because multiprocessing may or may not be involved). How can I reassign the input parameter to the copied value? Here’s a representation of the function:
from copy import deepcopy, copy
def myFunc(myObj,i):
myObj.x = 'start'
# I can't avoid this step:
modObj = deepcopy(myObj)
modObj.x = 'modified'
if i == 0:
myObj.x = modObj.x
elif i == 1:
myObj = modObj
elif i == 2:
myObj = copy(modObj)
elif i == 3:
myObj.__dict__ = modObj.__dict__
class MyClass(object):
def __init__(self):
self.x = "construct"
for i in range(4):
temp = MyClass()
myFunc(temp,i)
print i,temp.x
And here’s the output:
0 modified
1 start
2 start
3 modified
Since option #3 is so close to what I want to do, is there an “official” way to do it? E.g.
myObj.shallowcopy(modObj)
where this shallowcopy behaves similarly to the shallow copy in copy. One alternative would be to embed MyClass as a member of some other class, and pass that class to the function… but if I can do that, why can’t python just save me that step by copying over member data? I’ve read this, but they didn’t seem to come up with an answer for me.
Update: Ok, now that I understand more about the problem, I would suggest a combination of options 1 and 4: create public
update()anddictify()methods. These could be wrappers around option 4 or some variation likemyObj.__dict__.update(modObj.__dict__)— both of which are somewhat hackish.Or, they could be elegant, readable, self-documenting methods that accept and return (respectively) the appropriate dictionary representation of
self, which may or may not coincide withself.__dict__. I think the reason Python doesn’t have any built-in functionality for things like this is that there’s no truly general way to implement it, because not all objects have a__dict__. This kind of behavior has to have a customized implementation.If manipulating
__dict__is sufficient for your needs, fine, but you save yourself some trouble if you hide that manipulation behind an abstraction that can be altered later, if you decide you want to implement__slots__or something like that.(Leaving the below for historical purposes)
This confuses me: “I do not want to return the modified object (because multiprocessing may or may not be involved).” If you mean the
multiprocessingmodule, then even options 0 and 3 will fail, because processes don’t share memory.See? If you want to transfer data between processes, you have to use one of
multiprocessing‘s built-in types.If you aren’t using
multiprocessing, then aQueuewill serve as well as any other mutable container for this purpose. That’s the closest there is to an “official” way to pass by reference in Python.