繁体   English   中英

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

[英]Problems with deepcopying sys.stdout in python

我在copy.deepcopy中遇到以下问题。 与复制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()

导致错误

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

由于各种原因,我需要进行深度复制(因为在更复杂的情况下以各种方式更改example_2,因此需要进行深度复制)。 但是,当它深度复制sys.stdout ,它会将其从输出转移到屏幕上,而是输出到一个关闭的文件中,然后该文件上面的错误。 一个明显的解决方案是

example_2 = copy.deepcopy(example_1)
example_2.outa = example_1.outa

有没有更好的办法解决这个问题? 还是更好的复制方式? 谢谢!

您可以使用magicmethod__deepcopy__编写自己的对象深度__deepcopy__机制

这是您的代码的工作示例:

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

这不是理想的选择(如果将其子类化,则需要注意,因为child的Deepcopy将返回parent的实例!),但是应该给您一个想法,如何在您的实际应用程序中实现它。

您可以自定义实例的复制方式,并使用__deepcopy__方法共享输出(如果是sys.stdout

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属性的逻辑。 例如,也许不复制打开文件对象的任何内容是个好主意,或者永远不要复制该属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM