在python中深度复制sys.stdout的问题

时间:2016-12-08 10:35:10

标签: python

我在copy.deepcopy中遇到以下问题。它与深度复制sys.stdout

有关
Condition1: cout<<"Enter age: ";
cin>>age;

if (age>18){
cout<<"Welcome"<<endl;
//same code...
}
else{
goto Condition1;
}

导致错误

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()

由于各种原因,我需要深度复制(因为我在更复杂的情况下以各种方式更改example_2,因此需要深度复制)。但是,当它深入显示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 时,它会将其从输出传输到屏幕,而是将其输出到一个已关闭的文件,然后获取上述错误。一个明显的解决方案是

sys.stdout

有更好的解决方法吗?或者更好的深度复制方式?谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用magicmethod __deepcopy__

为deepcoping对象编写自己的机制

以下是您的代码的工作示例:

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()

这并不理想(如果对子类进行子类化,你需要小心,因为孩子的深层复制将返回父项的实例!)但是应该让你知道如何在你的现实应用程序中实现它。

答案 1 :(得分:0)

您可以自定义实例的复制方式,只需使用sys.stdout方法分享输出__deepcopy__

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)

您可以调整何时复制outa属性的逻辑;例如,或许不复制任何打开文件对象是个好主意,或者永远不会复制该属性。