2011-08-10 22 views
6

我認爲print聲明只是在sys.stdout(默認)對象上調用.write()方法。pythons'print'語句不調用.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方法,很明顯我很想念計算基本。

+0

http://stefaanlippens.net/redirect_python_print是否有幫助? – Evpok

+1

'print'有它自己對'stdout'的引用。 – agf

+0

@Evpok我想如果他試圖重定向打印而不是使用正常的日誌記錄,他可能不想修改預先存在的'print'語句。 – agf

回答

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也嘗試但這沒有什麼區別。

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個loglines):

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個記錄中的完整打印語句?

1

This article解釋您的問題。基本上,如果sys.stdoutfile的子類,那麼print將繞過sys.stdout.write並直接寫入sys.stdout.fd

您的問題的解決方案是使用組合而不是繼承file

+1

你能舉個例子嗎? – Hobblin