Saya ingin mengarahkan cetak ke file .txt menggunakan python. Saya memiliki loop 'untuk', yang akan 'mencetak' output untuk setiap file .bam saya sementara saya ingin mengarahkan SEMUA output ini ke satu file. Jadi saya mencoba memasukkan
f = open('output.txt','w'); sys.stdout = f
di awal skrip saya. Namun saya tidak mendapatkan apa pun di file .txt. Skrip saya adalah:
#!/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....
Jadi apa masalahnya? Ada cara lain selain sys.stdout ini?
Saya perlu hasil saya terlihat seperti:
Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)
python
file-writing
Lihat ke Dalam
sumber
sumber
f.write(data)
?f.write(line)
- Menyisipkan jeda baris di akhir.f.write(line)
tidak menambahkan jeda baris ke data.f.write(line+'\n')
Namun, selalu bisa ..Jawaban:
Cara paling jelas untuk melakukan ini adalah mencetak ke objek file:
Namun, mengarahkan stdout juga berfungsi untuk saya. Mungkin baik untuk skrip satu kali seperti ini:
Mengarahkan secara eksternal dari shell itu sendiri adalah pilihan lain yang baik:
Pertanyaan Lain:
Apa nama file pertama dalam skrip Anda? Saya tidak melihatnya diinisialisasi.
Dugaan pertama saya adalah bahwa glob tidak menemukan bamfiles, dan karena itu for loop tidak berjalan. Periksa apakah folder tersebut ada, dan cetak bamfiles dalam skrip Anda.
Juga, gunakan os.path.join dan os.path.basename untuk memanipulasi path dan nama file.
sumber
Anda dapat mengalihkan cetak dengan
>>
operator.Dalam kebanyakan kasus, Anda lebih baik menulis ke file secara normal.
atau, jika Anda memiliki beberapa item yang ingin Anda tulis dengan spasi di antaranya, seperti
print
:sumber
sys.stdout
, bukan bahwa itu adalah ide yang baik.Karena objek file biasanya berisi
write()
metode, yang perlu Anda lakukan adalah memasukkan objek file ke dalam argumennya.Tulis / Timpa ke File
Tulis / Tambahkan ke File
sumber
sys.stdout
:(Ini bekerja dengan sempurna:
Sekarang halo akan ditulis ke file test.txt. Pastikan untuk menutup
stdout
denganclose
, tanpa itu konten tidak akan disimpan dalam filesumber
sys.stdout.close()
, jika Anda mengetikkan apa pun di shell python itu akan menampilkan kesalahan sebagaiValueError: I/O operation on closed file.
imgur.com/a/xby9P . Cara terbaik untuk menangani ini adalah mengikuti apa yang diposting @Gringo SuaveJangan gunakan
print
, gunakanlogging
Anda dapat mengubah
sys.stdout
untuk menunjuk ke file, tetapi ini adalah cara yang cukup kikuk dan tidak fleksibel untuk menangani masalah ini. Alih-alih menggunakanprint
, gunakanlogging
modul.Dengan
logging
, Anda dapat mencetak seperti yang Anda inginkanstdout
, atau Anda juga dapat menulis output ke file. Anda bahkan dapat menggunakan tingkat pesan yang berbeda (critical
,error
,warning
,info
,debug
), misalnya, hanya mencetak isu utama untuk konsol, tapi masih log tindakan kode kecil ke sebuah file.Contoh sederhana
Impor
logging
, dapatkanlogger
, dan atur tingkat pemrosesan:Jika Anda ingin mencetak ke stdout:
Jika Anda ingin juga menulis ke file (jika Anda hanya ingin menulis ke file lewati bagian terakhir):
Lalu, di mana pun Anda akan menggunakan
print
gunakan salah satulogger
metode:Untuk mempelajari lebih lanjut tentang menggunakan
logging
fitur yang lebih canggih , bacalogging
tutorial yang sangat baik di Python docs .sumber
Solusi termudah tidak melalui python; itu melalui shell. Dari baris pertama file Anda (
#!/usr/bin/python
) Saya kira Anda menggunakan sistem UNIX. Cukup gunakanprint
pernyataan seperti biasanya, dan jangan buka file sama sekali dalam skrip Anda. Saat Anda menjalankan file, alih-alihuntuk menjalankan file, gunakan
di mana Anda mengganti
<filename>
dengan nama file yang Anda inginkan untuk output. The>
tanda mengatakan (paling) kerang untuk set stdout ke file dijelaskan oleh token berikut.Satu hal penting yang perlu disebutkan di sini adalah "script.py" harus dapat dieksekusi agar
./script.py
dapat dijalankan.Jadi sebelum menjalankan
./script.py
, jalankan perintah inichmod a+x script.py
(membuat skrip dapat dieksekusi untuk semua pengguna)sumber
print
ke file. Akan masuk akal untuk mengharapkan stdout (jejak tumpukan dan sejenisnya) untuk tetap mencetak ke terminal.Jika Anda menggunakan Linux, saya sarankan Anda untuk menggunakan
tee
perintah. Implementasinya seperti ini:Jika Anda tidak ingin mengubah apa pun dalam kode, saya pikir ini mungkin solusi terbaik. Anda juga dapat mengimplementasikan logger tetapi Anda perlu melakukan beberapa perubahan pada kode.
sumber
Anda mungkin tidak menyukai jawaban ini, tapi saya pikir itu BENAR. Jangan mengubah tujuan stdout Anda kecuali jika benar-benar diperlukan (mungkin Anda menggunakan perpustakaan yang hanya menghasilkan stdout ??? jelas tidak terjadi di sini).
Saya pikir sebagai kebiasaan yang baik Anda harus menyiapkan data Anda sebelumnya sebagai sebuah string, kemudian buka file Anda dan tulis semuanya sekaligus. Ini karena operasi input / output semakin lama Anda membuka file handle, semakin besar kemungkinan terjadi kesalahan pada file ini (kesalahan kunci file, kesalahan i / o, dll). Hanya melakukan semuanya dalam satu operasi tidak meninggalkan pertanyaan untuk ketika itu mungkin salah.
Ini sebuah contoh:
Dan kemudian ketika Anda sudah selesai mengumpulkan "garis data" Anda satu baris per item daftar, Anda dapat bergabung dengan mereka dengan beberapa
'\n'
karakter untuk membuat semuanya menjadi tabel output; mungkin bahkan membungkus pernyataan output Anda dalam sebuahwith
blok, untuk keamanan tambahan (secara otomatis akan menutup gagang output Anda bahkan jika ada yang salah):Namun jika Anda memiliki banyak data untuk ditulis, Anda dapat menulisnya satu per satu. Saya tidak berpikir itu relevan dengan aplikasi Anda tetapi inilah alternatifnya:
sumber
Jika pengalihan
stdout
berfungsi untuk masalah Anda, jawaban Gringo Suave adalah demonstrasi yang baik untuk melakukannya.Untuk membuatnya lebih mudah , saya membuat versi menggunakan contextmanager untuk sintaks panggilan singkat yang digeneralisasikan menggunakan
with
pernyataan:Untuk menggunakannya, Anda cukup melakukan hal berikut (berasal dari contoh Suave):
Ini berguna untuk mengarahkan secara selektif
print
ketika sebuah modul menggunakannya dengan cara yang tidak Anda sukai. Satu-satunya kelemahan (dan ini adalah dealbreaker untuk banyak situasi) adalah tidak bekerja jika seseorang menginginkan banyak utas dengan nilai berbedastdout
, tetapi itu membutuhkan metode yang lebih baik dan lebih umum: akses modul tidak langsung. Anda dapat melihat implementasi itu dalam jawaban lain untuk pertanyaan ini.sumber
Mengubah nilai sys.stdout tidak mengubah tujuan semua panggilan untuk dicetak. Jika Anda menggunakan cara alternatif untuk mengubah tujuan cetak, Anda akan mendapatkan hasil yang sama.
Bug Anda ada di tempat lain:
sumber
Sesuatu untuk memperluas fungsi cetak untuk loop
sumber
while
dan tidak perlu menutup file saat menggunakanwith