Я хочу перенаправить печать в файл .txt с помощью Python. У меня есть цикл for, который будет «печатать» выходные данные для каждого из моих файлов .bam, в то время как я хочу перенаправить ВСЕ эти выходные данные в один файл. Вот я и попытался поставить
f = open('output.txt','w'); sys.stdout = f
в начале моего сценария. Однако я ничего не получаю в файле .txt. Мой сценарий:
#!/usr/bin/python
import os,sys
import subprocess
import glob
from os import path
f = open('output.txt','w')
sys.stdout = f
path= '/home/xug/nearline/bamfiles'
bamfiles = glob.glob(path + '/*.bam')
for bamfile in bamfiles:
filename = bamfile.split('/')[-1]
print 'Filename:', filename
samtoolsin = subprocess.Popen(["/share/bin/samtools/samtools","view",bamfile],
stdout=subprocess.PIPE,bufsize=1)
linelist= samtoolsin.stdout.readlines()
print 'Readlines finished!'
........print....
........print....
Так в чем проблема? Любой другой способ, кроме этого sys.stdout?
Мне нужно, чтобы мой результат выглядел так:
Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)
python
file-writing
LookIntoEast
источник
источник
f.write(data)
?f.write(line)
- он вставляет разрыв строки в конце.f.write(line)
не добавляет разрыв данных в данные.f.write(line+'\n')
..Ответы:
Наиболее очевидный способ сделать это - напечатать объект файла:
Тем не менее, перенаправление stdout также работает для меня. Это, вероятно, хорошо для одноразового сценария, такого как этот:
Перенаправление извне из самой оболочки является еще одним хорошим вариантом:
Другие вопросы:
Какое первое имя файла в вашем сценарии? Я не вижу его инициализированным.
Мое первое предположение состоит в том, что glob не находит никаких bamfiles, и поэтому цикл for не запускается. Убедитесь, что папка существует, и распечатайте bamfiles в вашем скрипте.
Также используйте os.path.join и os.path.basename для манипулирования путями и именами файлов.
источник
Вы можете перенаправить печать с
>>
оператором.В большинстве случаев вам лучше просто записать в файл нормально.
или, если у вас есть несколько элементов, которые вы хотите написать с пробелами между ними, например
print
:источник
sys.stdout
, но это не было хорошей идеей.Поскольку файловый объект обычно содержит
write()
метод, все, что вам нужно сделать, это передать объект файла в его аргумент.Запись / перезапись в файл
Написать / Добавить в файл
источник
sys.stdout
:(Это прекрасно работает:
Теперь привет будет записан в файл test.txt. Убедитесь, что закрыли
stdout
сclose
, без него содержимое не будет сохранено в файлисточник
sys.stdout.close()
, если выValueError: I/O operation on closed file.
введете что-либо в оболочку python, это будет отображать ошибку как imgur.com/a/xby9P . Лучший способ справиться с этим - следовать тому, что написал @Gringo SuaveНе используйте
print
, используйтеlogging
Вы можете изменить
sys.stdout
указатель на файл, но это довольно неуклюжий и негибкий способ решения этой проблемы. Вместо использованияprint
используйтеlogging
модуль.С помощью
logging
вы можете печатать так же, как выstdout
, или вы также можете записать вывод в файл. Вы даже можете использовать различные уровни сообщений (critical
,error
,warning
,info
,debug
), например, печатать только основные вопросы , на консоль, но все - таки войти незначительную коду действие в файл.Простой пример
Импортируйте
logging
, получитеlogger
и установите уровень обработки:Если вы хотите распечатать на стандартный вывод:
Если вы также хотите записать в файл (если вы хотите записать только в файл, пропустите последний раздел):
Затем, где бы вы ни использовали,
print
используйте один изlogger
методов:Чтобы узнать больше об использовании более сложных
logging
функций, прочитайте превосходноеlogging
руководство в документации по Python .источник
Самое простое решение не через Python; его через оболочку. Из первой строки вашего файла (
#!/usr/bin/python
) я предполагаю, что вы работаете в системе UNIX. Просто используйтеprint
операторы, как обычно, и вообще не открывайте файл в вашем скрипте. Когда вы идете, чтобы запустить файл, а нечтобы запустить файл, используйте
где вы заменяете
<filename>
на имя файла, в который хотите включить вывод.>
Маркер говорит (большинство) оболочки , чтобы установить стандартный вывод в файл , описываемый следующим токен.Здесь важно упомянуть одну важную вещь: для запуска «script.py» необходимо сделать исполняемым
./script.py
.Поэтому перед запуском
./script.py
выполните эту командуchmod a+x script.py
(сделать сценарий исполняемым для всех пользователей)источник
print
в файл. Было бы разумно ожидать, что стандартный вывод (следы стека и тому подобное) все еще будет печататься в терминал.Если вы используете Linux, я предлагаю вам использовать
tee
команду. Реализация идет так:Если вы не хотите ничего менять в коде, я думаю, что это может быть лучшим решением. Вы также можете реализовать регистратор, но вам нужно внести некоторые изменения в код.
источник
Вам может не понравиться этот ответ, но я думаю, что он правильный. Не меняйте место назначения stdout, если это не является абсолютно необходимым (может быть, вы используете библиотеку, которая выводит только в stdout - здесь явно не так).
Я считаю хорошей привычкой заранее подготовить данные в виде строки, а затем открыть файл и написать все сразу. Это связано с тем, что чем дольше выполняются операции ввода / вывода, тем больше вероятность возникновения ошибки в этом файле (ошибка блокировки файла, ошибка ввода-вывода и т. Д.). Простое выполнение всего за одну операцию не оставляет вопроса о том, когда это могло пойти не так.
Вот пример:
И затем, когда вы все закончите, собирая свои «строки данных» по одной строке на элемент списка, вы можете объединить их с некоторыми
'\n'
символами, чтобы сделать все это выводимым; может быть, даже обернуть ваш оператор вывода вwith
блок, для дополнительной безопасности (автоматически закроет ваш дескриптор вывода, даже если что-то пойдет не так):Однако, если у вас есть много данных для записи, вы можете написать их по одному фрагменту за раз. Я не думаю, что это имеет отношение к вашему заявлению, но вот альтернатива:
источник
Если перенаправление
stdout
работает для вашей проблемы, ответ Gringo Suave является хорошей демонстрацией того, как это сделать.Чтобы сделать это еще проще , я сделал версию, использующую контекстные менеджеры для краткого обобщенного синтаксиса вызова, используя
with
оператор:Чтобы использовать его, вы просто делаете следующее (полученный из примера Suave):
Это полезно для выборочного перенаправления,
print
когда модуль использует его так, как вам не нравится. Единственный недостаток (а во многих ситуациях это является нарушителем правил) заключается в том, что он не работает, если требуется несколько потоков с разными значениямиstdout
, но для этого требуется лучший, более обобщенный метод: косвенный доступ к модулю. Вы можете увидеть реализацию этого в других ответах на этот вопрос.источник
Изменение значения sys.stdout меняет назначение всех вызовов для печати. Если вы используете альтернативный способ изменить место назначения печати, вы получите тот же результат.
Ваша ошибка в другом месте:
источник
Что-то, чтобы расширить функцию печати для петель
источник
while
и не нужно закрывать файл при использованииwith