Lebih
Bagaimana anda baca dari stdin?
I'm mencoba untuk melakukan beberapa kode golf tantangan, tetapi mereka semua membutuhkan input yang akan diambil dari stdin
. Bagaimana cara saya mendapatkan bahwa di Python?
1378
22
Anda bisa menggunakan
fileinput
modul:fileinput
akan loop melalui semua baris yang di input ditentukan sebagai nama file yang diberikan pada argumen baris perintah, atau standar input jika tidak ada argumen yang diberikan.Catatan:
line
akan berisi trailing newline; untuk menghapusnya menggunakanjalur.rstrip()
Ada's beberapa cara untuk melakukannya.
sys.stdin
adalah file-seperti objek di mana anda dapat memanggil fungsi-fungsimembaca
ataureadlines
jika anda ingin membaca semuanya atau anda ingin membaca semuanya dan membaginya dengan baris baru secara otomatis. (Anda perlu untukimport sys
untuk ini untuk bekerja.)Jika anda ingin cepat pengguna untuk input, anda dapat menggunakan
raw_input
di Python 2.X, dan hanyainput
di Python 3.Jika anda benar-benar hanya ingin membaca opsi baris perintah, anda dapat mengaksesnya melalui sys.argv daftar.
Anda mungkin akan menemukan ini Wikibook artikel tentang I/O di Python menjadi referensi yang berguna juga.
``kebutu import sys
untuk baris di sys.stdin: print(baris) ``
Catatan bahwa ini akan mencakup karakter newline di akhir. Untuk menghapus baris pada akhirnya, menggunakan
jalur.rstrip()
sebagai @brittohalloran kata.Python juga memiliki built-in fungsi input()
dan
raw_input()`. Lihat dokumentasi Python di bawah Fungsi Built-in.Misalnya,
atau
Berikut ini's dari Belajar Python:
Pada Unix, anda bisa mengujinya dengan melakukan sesuatu seperti:
Pada Windows atau DOS, anda'd lakukan:
Jawabannya diusulkan oleh orang lain:
ini sangat sederhana dan pythonic, tetapi harus dicatat bahwa script akan menunggu sampai EOF sebelum memulai untuk iterate pada baris input.
Ini berarti bahwa
tail -f error_log | myscript.py
tidak akan memproses garis-garis seperti yang diharapkan.Yang benar skrip untuk sebuah use case akan sama:
UPDATE Dari komentar-komentar ini telah dihapus pada python 2 hanya mungkin ada buffering yang terlibat, sehingga anda akhirnya menunggu buffer untuk mengisi atau EOF sebelum mencetak panggilan yang dikeluarkan.
Kita dapat melihat bahwa
sys.stdin
di default mode teks: ``pythonJawaban lagi
Berikut ini's lengkap, mudah ditiru demo, menggunakan dua metode, fungsi bawaan,
input
(menggunakanraw_input
di Python 2), dansys.stdin
. Data yang dimodifikasi, sehingga pengolahan non-operasi. Untuk mulai dengan, let's membuat file untuk input:Dan menggunakan kode kita've sudah terlihat, kita dapat memeriksa bahwa kita've dibuat file:
Berikut ini's bantuan pada
sys.stdin.baca
dari Python 3:Fungsi bawaan,
input
(raw_input
di Python 2)Builtin fungsi
input
dibaca dari masukan standar sampai dengan baris baru, yang dilucuti (melengkapiprint
, yang menambahkan baris baru secara default.) Hal ini terjadi hingga sampai EOF (End Of File), di mana titik itu menimbulkanEOFError
. Dengan demikian, di sini's bagaimana anda dapat menggunakaninput
di Python 3 (atauraw_input
di Python 2) untuk baca dari stdin - jadi kami membuat modul Python yang kita sebut stdindemo.py:Dan let's mencetaknya kembali untuk memastikan itu's seperti yang kita harapkan:
Lagi,
input
membaca sampai baris baru dan pada dasarnya strip itu dari garis.print
menambahkan baris baru. Jadi sementara mereka berdua memodifikasi input, modifikasi mereka membatalkan. (Jadi mereka pada dasarnya sama lain's pelengkap.) Dan ketikainput
mendapat end-of-file karakter, itu menimbulkan EOFError, yang kita abaikan dan kemudian keluar dari program. Dan di Linux/Unix, kita bisa pipa dari kucing:Atau kita hanya bisa mengarahkan file dari stdin:
Kami juga dapat melaksanakan modul sebagai script:
Berikut ini's bantuan pada builtin
masukan
dari Python 3:sys.stdin
Di sini kita membuat sebuah demo script menggunakan
sys.stdin
. Cara yang efisien untuk iterate atas file-seperti objek adalah dengan menggunakan file-seperti objek sebagai iterator. Melengkapi metode untuk menulis ke stdout dari masukan ini adalah untuk hanya menggunakansys.stdout.menulis
:Cetak kembali keluar untuk memastikan itu terlihat benar:
Dan mengarahkan input ke file:
Golfed ke perintah:
File Deskriptor untuk Golf
Karena file deskriptor untuk
stdin
danstdout
adalah 0 dan 1 masing-masing, kita juga bisa melewati orang-orang untukterbuka
di Python 3 (bukan 2, dan perhatikan bahwa kita masih perlu 'w' untuk menulis ke stdout). Jika ini bekerja pada sistem anda, itu akan mencukur lebih banyak karakter.Python 2's
io.buka
apakah ini juga, tapi impor membutuhkan lebih banyak ruang:Menyikapi komentar lain dan jawaban
Satu komentar menunjukkan
''.bergabung(sys.stdin)
untuk bermain golf tapi yang's benar-benar lebih dari sys.stdin.read() - plus Python harus membuat tambahan daftar di memori (yang's bagaimanastr.bergabung
bekerja bila tidak diberikan daftar) - kontras:Atas jawabannya menunjukkan:
Tapi, karena
sys.stdin
mengimplementasikan file API, termasuk iterator protokol, yang's sama seperti ini:Jawaban lain tidak menyarankan hal ini. Hanya ingat bahwa jika anda melakukan hal itu dalam sebuah interpreter, anda'll perlu melakukan Pilih-a jika anda're di Linux atau Mac, atau Pilih-z pada Windows (setelah Enter) untuk mengirim end-of-file karakter untuk proses. Juga, jawaban itu menunjukkan
print(baris)
- yang menambahkan'\n'
sampai akhirprint(baris, end='')
bukan (jika di Python 2, anda'll perludari __masa__ impor print_function
). Penggunaan nyata-kasusfileinput
adalah untuk membaca di sebuah seri dari file.Ini akan echo standar input ke output standar:
Bangunan pada semua anwers menggunakan
sys.stdin
, anda juga dapat melakukan sesuatu seperti berikut untuk membaca dari sebuah argumen file jika setidaknya salah satu argumen yang ada, dan jatuh kembali ke stdin sebaliknya:dan menggunakannya sebagai
atau
atau bahkan
Yang akan membuat anda Python script berperilaku seperti banyak GNU/Unix program-program seperti
kucing
,grep
dansed
.argparse
adalah solusi yang mudahContoh kompatibel dengan Python versi 2 dan 3:
Anda dapat menjalankan script ini dalam banyak cara:
1. Menggunakan
stdin
atau lebih pendek dengan mengganti
echo
oleh di sini string:Chip berikut kode yang akan membantu anda (ini akan membaca semua dari stdin pemblokiran kepada
EOF
, menjadi satu string):Coba ini:
dan cek dengan:
Anda bisa baca dari stdin dan kemudian menyimpan input ke "data" sebagai berikut:
Baca dari
sys.stdin
, tapi untuk membaca data biner pada Windows, anda perlu ekstra hati-hati, karenasys.stdin
tidak dibuka dalam mode teks, dan itu akan merusak\r\n
dan menggantinya dengan\n
.Solusinya adalah dengan mengatur mode ke biner jika Windows + Python 2 terdeteksi, dan pada Python 3 menggunakan
sys.stdin.buffer
.Saya cukup kagum tidak ada yang telah disebutkan hack ini sejauh ini:
kompatibel dengan kedua python2 dan python3
Masalah yang saya miliki dengan solusi
adalah bahwa jika anda don't lulus data ke stdin, itu akan memblokir selamanya. Yang's mengapa saya cinta jawaban: periksa jika ada beberapa data pada stdin pertama, dan kemudian membacanya. Ini adalah apa yang akhirnya saya lakukan:
Aku punya beberapa masalah ketika mendapatkan ini untuk bekerja untuk membaca lebih soket disalurkan untuk itu. Ketika soket punya ditutup mulai mengembalikan string kosong di dalam loop. Jadi ini adalah solusi untuk hal ini (yang saya hanya diuji di linux, tapi harapan itu bekerja di semua sistem yang lain)
Jadi jika anda mulai mendengarkan pada soket ini akan bekerja dengan baik (misalnya di bash):
Dan anda bisa menyebutnya dengan telnet atau hanya mengarahkan browser ke localhost:12345
Mengenai hal ini:
untuk baris di sys.stdin:
Saya hanya mencoba pada python 2.7 (mengikuti orang lain's saran) untuk file yang sangat besar, dan saya don't merekomendasikan hal ini, justru untuk alasan yang disebutkan di atas (tidak ada yang terjadi untuk waktu yang lama).
Aku berakhir dengan sedikit lebih pythonic solusi (dan bekerja pada file yang lebih besar):
Kemudian saya dapat menjalankan script secara lokal sebagai:
Untuk Python 3 yang akan sama:
Ini pada dasarnya adalah bentuk sederhana dari kucing(1), sejak itu doesn't menambahkan baris baru setelah setiap baris. Anda dapat menggunakan ini (setelah Anda menandai file yang dapat dijalankan menggunakan
chmod +x cat.py
seperti:Ada
os.baca(0, x)
yang berbunyi xbytes dari 0 yang mewakili stdin. Ini adalah sebuah unbuffered baca, lebih rendah dari tingkat sys.stdin.read()