I have the following problem with copy.deepcopy. It is to do with deepcopying sys.stdout
import sys, copy
class Example:
def __init__(self, value, outa=sys.stdout):
self.value = value
self.outa = outa
def saying_hello_world(self):
print>>self.outa, "Hello world! My value is ", self.value
example_1 = Example(3)
example_1.saying_hello_world()
example_2 = copy.deepcopy(example_1)
example_2.value = 5
example_2.saying_hello_world()
Leads to error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in saying_hello_world
ValueError: I/O operation on closed file
For various reasons I need to deepcopy (as I change example_2 in various ways in my more complex situation, and so need a deepcopy). However, when it deepcopies sys.stdout
, it transfers it from outputting into thee screen and instead outputs it to a closed file, which then gets the error above. An obvious solution to this is
example_2 = copy.deepcopy(example_1)
example_2.outa = example_1.outa
Is there a better way around this? Or a better way of deepcopying? Thank you!
You can write your own mechanism for deepcoping object using magicmethod __deepcopy__
Here is working example for your code:
import sys, copy
class Example:
def __init__(self, value, outa=sys.stdout):
self.value = value
self.outa = outa
def saying_hello_world(self):
print>>self.outa, "Hello world! My value is ", self.value
def __deepcopy__(self, memo):
# deepcopy self.value, but pass just a reference of self.outa
return Example(copy.deepcopy(self.value, memo), self.outa)
example_1 = Example(3)
example_1.saying_hello_world()
example_2 = copy.deepcopy(example_1)
example_2.value = 5
example_2.saying_hello_world()
It is not ideal (you'll need care if subclassing this, as deepcopy of child will return instance of parent!) but should give you an idea how to implement this in your real life application.
You can customise how your instances are copied, and just share the output if it is sys.stdout
, using the __deepcopy__
method:
class Example:
def __init__(self, value, outa=sys.stdout):
self.value = value
self.outa = outa
def saying_hello_world(self):
print >> self.outa, "Hello world! My value is ", self.value
def __deepcopy__(self, memo):
outa = self.outa if self.outa is sys.stdout else deepcopy(self.outa, memo)
return Example(deepcopy(self.value, memo), outa)
You can adjust the logic for when to copy the outa
attribute; perhaps not copying anything that is an open file object is a good idea, for example, or never copying that attribute.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.