Pertanyaan Bagaimana Anda membaca dari stdin dengan Python?


Saya mencoba melakukan beberapa hal kode golf tantangan, tetapi mereka semua membutuhkan masukan untuk diambil stdin. Bagaimana saya mendapatkannya dengan Python?


1171
2017-09-20 05:48


asal


Jawaban:


Anda bisa menggunakan fileinput modul:

import fileinput

for line in fileinput.input():
    pass

fileinput akan mengulang melalui semua garis dalam input yang ditentukan sebagai nama file yang diberikan dalam argumen baris perintah, atau input standar jika tidak ada argumen yang disediakan.


801
2017-09-20 05:53



Ada beberapa cara untuk melakukannya.

  • sys.stdin adalah objek mirip file tempat Anda dapat memanggil fungsi read atau readlines jika Anda ingin membaca semuanya atau Anda ingin membaca semuanya dan membaginya dengan baris baru secara otomatis. (Kamu butuh import sys agar ini berfungsi.)

  • Jika Anda menghendaki cepat pengguna untuk input, dapat Anda gunakan raw_input dengan Python 2.X, dan adil input dengan Python 3.

  • Jika Anda benar-benar hanya ingin membaca opsi baris perintah, Anda dapat mengaksesnya melalui sys.argv daftar.

Anda mungkin akan menemukan artikel Wikibook ini tentang I / O dengan Python menjadi referensi yang berguna juga.


584
2017-07-20 10:30



import sys

for line in sys.stdin:
    print line

331
2018-03-03 19:05



Python juga memiliki fungsi built-in input() dan raw_input(). Lihat dokumentasi Python di bawah Fungsi Terpasang.

Sebagai contoh,

name = raw_input("Enter your name: ")   # Python 2.x

atau

name = input("Enter your name: ")   # Python 3

180
2017-09-30 09:08



Ini berasal Belajar Python:

import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."

Di Unix, Anda bisa mengujinya dengan melakukan sesuatu seperti:

% cat countlines.py | python countlines.py 
Counted 3 lines.

Pada Windows atau DOS, Anda akan melakukan:

C:\> type countlines.py | python countlines.py 
Counted 3 lines.

160
2017-07-30 04:10



Jawaban yang diajukan oleh orang lain:

for line in sys.stdin:
  print line

sangat sederhana dan pythonic, tetapi harus dicatat bahwa skrip akan menunggu hingga EOF sebelum memulai iterate pada baris input.

Ini artinya itu tail -f error_log | myscript.py tidak akan memproses garis seperti yang diharapkan.

Skrip yang benar untuk kasus penggunaan seperti itu adalah:

while 1:
    try:
        line = sys.stdin.readline()
    except KeyboardInterrupt:
        break

    if not line:
        break

    print line

MEMPERBARUI
Dari komentar itu telah dibersihkan bahwa pada python 2 hanya mungkin ada buffering yang terlibat, sehingga Anda akhirnya menunggu buffer untuk mengisi atau EOF sebelum panggilan cetak dikeluarkan.


85
2017-08-09 16:31



Bagaimana Anda membaca dari stdin dengan Python?

Saya mencoba melakukan beberapa tantangan golf kode, tetapi mereka semua memerlukan masukan yang akan diambil dari stdin. Bagaimana saya mendapatkannya dengan Python?

Kamu dapat memakai:

  • sys.stdin - Objek mirip file - panggil sys.stdin.read() untuk membaca semuanya.
  • input(prompt) - berikan prompt opsional ke output, ia membaca dari stdin hingga baris baru pertama, yang di-strip. Anda harus melakukan ini berulang kali untuk mendapatkan lebih banyak garis, pada akhir masukan itu menimbulkan EOFError. (Mungkin tidak bagus untuk bermain golf.) Dalam Python 2, ini rawinput(prompt).
  • open(0).read() - Dengan Python 3 open menerima deskriptor file (Bilangan bulat mewakili sumber daya sistem operasi IO), dan 0 adalah pendeskripsi stdin. Ini mengembalikan objek seperti file seperti sys.stdin - Mungkin taruhan terbaik Anda untuk bermain golf.
  • open('/dev/stdin').read() - mirip dengan open(0), bekerja pada Python 2 dan 3, tetapi tidak pada Windows (atau bahkan Cygwin).
  • fileinput.input() - mengembalikan iterator melalui garis di semua file yang terdaftar sys.argv[1:], atau stdin jika tidak diberikan. Gunakan suka ''.join(fileinput.input()).

Kedua sys dan fileinput harus diimpor, masing-masing, tentu saja.

Cepat sys.stdin contoh yang kompatibel dengan Python 2 dan 3, Windows, Unix

Anda hanya perlu read dari sys.stdin, misalnya, jika Anda memasukkan data ke stdin:

$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo

contoh file

Katakan Anda memiliki file, inputs.txt, kami dapat menerima file itu dan menulisnya kembali:

python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt

Jawaban yang lebih panjang

Ini adalah demo yang lengkap dan mudah ditiru, menggunakan dua metode, fungsi bawaan, input (menggunakan raw_input dengan Python 2), dan sys.stdin. Data tidak dimodifikasi, sehingga pemrosesan tidak beroperasi.

Untuk memulainya, mari kita buat file untuk input:

$ python -c "print('foo\nbar\nbaz')" > inputs.txt

Dan dengan menggunakan kode yang sudah kami lihat, kami dapat memeriksa bahwa kami telah membuat file:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt 
foo
bar
baz

Ini bantuannya sys.stdin.read dari Python 3:

read(size=-1, /) method of _io.TextIOWrapper instance
    Read at most n characters from stream.

    Read from underlying buffer until we have n characters or we hit EOF.
    If n is negative or omitted, read until EOF.

Fungsi bawaan, input (raw_input dengan Python 2)

Fungsi bawaan input membaca dari input standar hingga baris baru, yang dilucuti (melengkapi print, yang menambahkan baris baru secara default.) Ini terjadi sampai mendapat EOF (Akhir File), pada titik mana ia naik EOFError.

Jadi, inilah cara Anda dapat menggunakannya input dengan Python 3 (atau raw_input dengan Python 2) untuk dibaca dari stdin - jadi kami membuat modul Python yang kami sebut stdindemo.py:

$ python -c "print('try:\n    while True:\n        print(input())\nexcept EOFError:\n    pass')" > stdindemo.py 

Dan mari cetak kembali untuk memastikannya seperti yang kami harapkan:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py 
try:
    while True:
        print(input())
except EOFError:
    pass

Lagi, input membaca hingga baris baru dan pada dasarnya menghapusnya dari garis. print menambahkan baris baru. Jadi ketika keduanya memodifikasi input, modifikasi mereka dibatalkan. (Jadi pada dasarnya mereka saling melengkapi.)

Dan kapan input mendapat karakter end-of-file, itu memunculkan EOFError, yang kita abaikan dan kemudian keluar dari program.

Dan di Linux / Unix, kita dapat menyambungkan dari kucing:

$ cat inputs.txt | python -m stdindemo
foo
bar
baz

Atau kita bisa mengarahkan ulang file dari stdin:

$ python -m stdindemo < inputs.txt 
foo
bar
baz

Kami juga dapat menjalankan modul sebagai skrip:

$ python stdindemo.py < inputs.txt 
foo
bar
baz

Inilah bantuan di builtin input dari Python 3:

input(prompt=None, /)
    Read a string from standard input.  The trailing newline is stripped.

    The prompt string, if given, is printed to standard output without a
    trailing newline before reading input.

    If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
    On *nix systems, readline is used if available.

sys.stdin

Di sini kami membuat skrip demo menggunakan sys.stdin. Cara efisien untuk mengulang objek yang mirip file adalah dengan menggunakan objek seperti file sebagai iterator. Metode komplementer untuk menulis ke stdout dari input ini adalah dengan mudah digunakan sys.stdout.write:

$ python -c "print('import sys\nfor line in sys.stdin:\n    sys.stdout.write(line)')" > stdindemo2.py

Cetak kembali untuk memastikan kelihatannya benar:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py 
import sys
for line in sys.stdin:
    sys.stdout.write(line)

Dan mengarahkan input ke dalam file:

$ python -m stdindemo2 < inputs.txt
foo
bar
baz

Berlabuh menjadi komando:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz

File Descriptors for Golfing

Karena deskriptor file untuk stdin dan stdout masing-masing adalah 0 dan 1, kami juga dapat meneruskannya open dengan Python 3 (bukan 2, dan perhatikan bahwa kita masih membutuhkan 'w' untuk menulis ke stdout).

Jika ini berfungsi di sistem Anda, ini akan memangkas lebih banyak karakter.

$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

Python 2's io.open melakukan ini juga, tetapi impor membutuhkan lebih banyak ruang:

$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt 
foo
bar
baz

Mengatasi komentar dan jawaban lainnya

Satu komentar menunjukkan ''.join(sys.stdin) tapi itu sebenarnya lebih lama dari sys.stdin.read () - ditambah Python harus membuat daftar tambahan dalam memori (begitulah caranya str.join bekerja ketika tidak diberi daftar) - untuk kontras:

''.join(sys.stdin)
sys.stdin.read()

Jawaban teratas menunjukkan:

import fileinput

for line in fileinput.input():
    pass

Tapi, sejak itu sys.stdin mengimplementasikan file API, termasuk protokol iterator, itu sama saja seperti ini:

import sys

for line in sys.stdin:
    pass

Jawaban lainnya tidak sarankan ini. Ingat saja bahwa jika Anda melakukannya di interpreter, Anda harus melakukannya Ctrl-d jika Anda menggunakan Linux atau Mac, atau Ctrl-z di Windows (setelah Memasukkan) untuk mengirim karakter akhir-file ke proses. Juga, jawaban itu menunjukkan print(line) - yang menambahkan a '\n' sampai akhir - gunakan print(line, end='') sebagai gantinya (jika dengan Python 2, Anda akan membutuhkannya from __future__ import print_function).

Kasus penggunaan nyata untuk fileinput adalah untuk membaca dalam serangkaian file.


49
2017-07-29 15:04



Ini akan menggemakan input standar ke output standar:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()

36
2018-01-25 10:26