Выражение «print» в pythons не вызывает метод .write ()? - PullRequest
6 голосов
/ 11 августа 2011

Я думал, что оператор print только что вызвал метод .write () для объекта sys.stdout (по умолчанию).

но написав такой подкласс:

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 isn ' т звонит 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 ]

4 голосов
/ 11 августа 2011

По-видимому, это ограничение реализации 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 голосов
/ 11 августа 2011

Если вы поместите файл в переменную экземпляра, похоже, он будет работать.

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 журнале?

1 голос
/ 11 августа 2011

Эта статья объясняет вашу проблему.В основном, если sys.stdout является подклассом file, то print обходит sys.stdout.write и записывает напрямую в sys.stdout.fd.

. Решение вашей проблемы состоит в использовании композиции вместо подкласса file.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...