python'print'语句不调用.write()方法?

时间:2011-08-10 21:03:31

标签: python oop file inheritance printing

我认为print语句只调用sys.stdout(默认情况下)对象上的.write()方法。

但写了这样的子类:

import time

class logfile(file):
    def __init__(self, *args, **kwargs):
        file.__init__(self, *args, **kwargs)

    def write(self, logstr):
        if logstr[-1] != '\n': logstr += '\n'
        super(logfile, self).write(time.strftime('%D-%T ') + str(logstr))

如果我创建一个logfile对象并调用write方法,但尝试将sys.stdout对象更改为logfile的实例时似乎有效似乎print没有调用write。也许writelines

使用此:

#!/usr/bin/python

from myfile import logfile
import sys

sys.stdout = logfile('somefile', 'w')

print 'this is a test'
sys.stdout.write('this is another test')

我的输出文件'somefile'包含:

this is a test
08/10/11-16:59:47 this is another test

您可以看到输出文件中的第一行是我尝试的print,第二行是sys.stdout.write中使用的

我认为print只是调用write方法 - 显然我错过了一些基本的东西。

3 个答案:

答案 0 :(得分:4)

显然,这是对Python 2实现的限制,其中print是一个语句而不是带有副作用的表达式(就像在Python 3中一样)。

我将代码重写为适用于Python 3的东西:

from io import FileIO
import time

class logfile(FileIO):
  def __init__(self, *args, **kwargs):
    FileIO.__init__(self, *args, **kwargs)

  def write(self, logstr):
    if logstr[-1] == '\n': logstr = logstr[:-1]
    super(logfile, self).write(bytes(time.strftime('%D-%T ') + str(logstr), 'UTF-8'))

import sys

sys.stdout = logfile('somefile', 'w')

print("This is a test")
sys.stdout.write('this is another test')

据我所知,没有办法在Python 2中创建相同的行为。

我也尝试使用from __future__ import print_function,但没有任何区别。

答案 1 :(得分:2)

如果将文件放在实例变量中,它似乎可以正常工作。

import time

class logfile(object):
    def __init__(self, *args, **kwargs):
        self.f = file(*args, **kwargs)
    def write(self, logstr):
        if logstr[-1] != '\n': logstr += '\n'
        self.f.write(time.strftime('%D-%T ') + str(logstr))

不幸的是,它记录了额外的空行,这里有一个解决方案(print '2', '3', '4'写入3个条目):

class logfile(object):
    def __init__(self, *args, **kwargs):
        self.f = file(*args, **kwargs)
        self.c = False
    def write(self, logstr):
        self.c = not self.c
        if logstr[-1] != '\n': logstr += '\n'
        if self.c:
            self.f.write(time.strftime('%D-%T ') + str(logstr))

这一行记录整行(注意:print "4\n", "5"仍然是2个日志):

class logfile(object):
    def __init__(self, *args, **kwargs):
        self.f = file(*args, **kwargs)
        self.newline = True
    def write(self, logstr):
        if self.newline:
            self.f.write(time.strftime('%D-%T '))
        self.f.write(logstr)
        self.newline = logstr[-1] == '\n'

有人知道如何在1个日志中处理完整的打印语句吗?

答案 2 :(得分:1)

This article解释了您的问题。基本上,如果sys.stdoutfile的子类,则print会绕过sys.stdout.write并直接写入sys.stdout.fd

问题的解决方案是使用合成而不是子类化file

相关问题