如何在Python 3中覆盖file.write()?

时间:2010-06-15 14:23:15

标签: python python-3.x

下面的代码适用于Python 2.6,但不适用于Python 3.x:

old_file_write = file.write 

class file():
    def write(self, d):
        if isinstance(d, types.bytes):
            self.buffer.write(d)
        else:
            old_file_write(d)

# ... some code I cannot change or do not want to change
f = open("x")
f.write("...")
f.write(b"...")
sys.stdout.write(b"...")
sys.stdout.write("...")
print(b"...")
print("...")

问题是在Python 3.x中第一行会产生错误:

NameError: name 'file' is not defined

如何在Python 3.x中完成这项工作?

事实上,两年后,我仍在寻找适用于两个版本(2.5 +和3.x)的解决方案。

对于那些仍然想知道我为什么要这样做的人来说,只是为了能够制作旧代码(其他代码,有时你无法修改)来使用更新版本的python。

这不是关于我的代码,而是关于如何编写一些可以很好地处理错误代码的代码:)

3 个答案:

答案 0 :(得分:3)

我看到两个问题。

1:您的file类不是从任何特定类继承的。如果我正确地解释了这种情况,它应该是io.TextIOWrapper的子类。

2:在Python 2.6和3.x中,types模块(首先需要导入)没有元素bytes。建议的方法是单独使用bytes

Redone片段:

import io, sys

class file(io.TextIOWrapper):
    def write(self, d, encoding=sys.getdefaultencoding()):
        if isinstance(d, bytes):
            d = d.decode(encoding)
        super().write(d)

old_stdout = sys.stdout    # In case you want to switch back to it again

sys.stdout = file(open(output_file_path, 'w').detach())  # You could also use 'a', 'a+', 'w+', 'r+', etc.

现在它应该按照您指定的输出文件使用sys.stdout.write执行您想要的操作。 (如果您不希望写入磁盘上的文件,而是希望写入默认的sys.stdout缓冲区,则使用sys.stdout = file(sys.stdout.detach())可能会有效。)

请注意,由于Python 3.x没有file类,但2.6确实有io模块,因此您必须使用io的其中一个类模块。我上面的代码只是一个例子,如果你想要它更灵活,你必须自己解决这个问题。也就是说,根据您要写入的文件类型/您正在写入的模式,您可能希望在io中使用其他类。

答案 1 :(得分:0)

old_file_write = file.write 

您正在使用file类的类级方法。

old_file_write(d)

永远不应该有效。我相信你还在复制和粘贴错误。

我想你可能已经

old_file_write(self,d)

哪些可能有效。

你的方法不是很好。想一想。

class MyKindOfFile( file ):
    def write(self, d):
        if isinstance(d, types.bytes):
            self.buffer.write(d)
        else:
            super( MyFindOfFile, write )(d)

这将为您带来更多好处,因为它以更典型的方式使用简单继承。

答案 2 :(得分:0)

file个对象可以写入字节,但您需要以正确的模式打开文件

fp = open('file.bin', 'wb') # open in binary mode
fp.write(b"some bytes") 
pf.close()

如果要将字符串写入磁盘,则需要先对其进行编码。