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?

Anda bisa menggunakan fileinput modul:

import fileinput

for line in fileinput.input():
    pass

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 menggunakan jalur.rstrip()

Komentar (1)

Ada's beberapa cara untuk melakukannya.

  • sys.stdin adalah file-seperti objek di mana anda dapat memanggil fungsi-fungsi membaca atau readlines jika anda ingin membaca semuanya atau anda ingin membaca semuanya dan membaginya dengan baris baru secara otomatis. (Anda perlu untuk import sys untuk ini untuk bekerja.)

  • Jika anda ingin cepat pengguna untuk input, anda dapat menggunakan raw_input di Python 2.X, dan hanya input 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.

Komentar (0)

``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.

Komentar (4)

Python juga memiliki built-in fungsi input()danraw_input()`. Lihat dokumentasi Python di bawah Fungsi Built-in.

Misalnya,

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

atau

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

Berikut ini's dari Belajar Python:

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

Pada Unix, anda bisa mengujinya dengan melakukan sesuatu seperti:

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

Pada Windows atau DOS, anda'd lakukan:

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

Jawabannya diusulkan oleh orang lain:

for line in sys.stdin:
  print line

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:

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

    if not line:
        break

    print line

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.

Komentar (7)

Bagaimana anda baca dari stdin di Python?

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? Anda dapat menggunakan:

  • sys.stdin - file-seperti objek - sebut sys.stdin.read() untuk membaca semuanya.
  • input(prompt) - lulus opsional prompt untuk output, membaca dari stdin up untuk pertama newline, yang strip. Anda'd harus melakukan ini berulang kali untuk mendapatkan lebih banyak garis, pada akhir dari masukan itu menimbulkan EOFError. (Mungkin tidak bagus untuk bermain golf.) Di Python 2, ini adalah rawinput(prompt).
  • open(0).read() - Di Python 3, fungsi bawaan terbuka menerima file deskriptor (bilangan bulat yang mewakili sistem operasi IO sumber daya), dan 0 adalah kata kunci stdin. Mengembalikan file-seperti objek seperti sys.stdin - mungkin anda bertaruh terbaik untuk bermain golf. Di Python 2, ini adalah io.open.
  • terbuka('/dev/stdin').read() - mirip dengan open(0), bekerja pada Python 2 dan 3, tapi tidak di Windows (atau bahkan Cygwin).
  • fileinput.input() - mengembalikan sebuah iterator atas garis-garis di seluruh berkas yang tercantum dalam sys.argv[1:], atau stdin jika tidak diberikan. Menggunakan seperti''.bergabung(fileinput.input()). Kedua sys dan fileinput harus diimpor, masing-masing, tentu saja.

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

    Anda hanya perlu untuk membaca dari sys.stdin, misalnya, jika anda pipa data untuk stdin:

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

Kita dapat melihat bahwa sys.stdin di default mode teks: ``python

import sys sys.stdin <_io.TextIOWrapper name='' modus='r' encoding='UTF-8'> ``

file contoh

Katakanlah anda memiliki sebuah file, inputs.txt, kita bisa menerima file tersebut dan menuliskannya kembali:

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

Jawaban lagi

Berikut ini's lengkap, mudah ditiru demo, menggunakan dua metode, fungsi bawaan, input (menggunakan raw_input di Python 2), dan sys.stdin. Data yang dimodifikasi, sehingga pengolahan non-operasi. Untuk mulai dengan, let's membuat file untuk input:

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

Dan menggunakan kode kita've sudah terlihat, kita dapat memeriksa bahwa kita've dibuat file:

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

Berikut ini's bantuan pada sys.stdin.baca 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 di Python 2)

Builtin fungsi input dibaca dari masukan standar sampai dengan baris baru, yang dilucuti (melengkapi print, yang menambahkan baris baru secara default.) Hal ini terjadi hingga sampai EOF (End Of File), di mana titik itu menimbulkan EOFError. Dengan demikian, di sini's bagaimana anda dapat menggunakan input di Python 3 (atau raw_input di Python 2) untuk baca dari stdin - jadi kami membuat modul Python yang kita sebut stdindemo.py:

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

Dan let's mencetaknya kembali untuk memastikan itu's seperti yang kita harapkan:

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

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 ketika input 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:

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

Atau kita hanya bisa mengarahkan file dari stdin:

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

Kami juga dapat melaksanakan modul sebagai script:

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

Berikut ini's bantuan pada builtin masukan 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 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 menggunakan sys.stdout.menulis:

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

Cetak kembali keluar untuk memastikan itu terlihat 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 file:

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

Golfed ke perintah:

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

File Deskriptor untuk Golf

Karena file deskriptor untuk stdin dan stdout adalah 0 dan 1 masing-masing, kita juga bisa melewati orang-orang untuk terbuka 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 -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

Python 2's io.buka apakah ini juga, tapi impor membutuhkan lebih banyak ruang:

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

Menyikapi komentar lain dan jawaban

Satu komentar menunjukkan&#39;&#39;.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 bagaimana str.bergabung bekerja bila tidak diberikan daftar) - kontras:

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

Atas jawabannya menunjukkan:

import fileinput

for line in fileinput.input():
    pass

Tapi, karena sys.stdin mengimplementasikan file API, termasuk iterator protokol, yang's sama seperti ini:

import sys

for line in sys.stdin:
    pass

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 &#39;\n&#39; sampai akhir print(baris, end=&#39;&#39;) bukan (jika di Python 2, anda'll perlu dari __masa__ impor print_function). Penggunaan nyata-kasus fileinput adalah untuk membaca di sebuah seri dari file.

Komentar (0)

Ini akan echo standar input ke output standar:

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

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:

import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin    
for line in f:
#     Do your stuff

dan menggunakannya sebagai

$ python do-my-stuff.py infile.txt

atau

$ cat infile.txt | python do-my-stuff.py

atau bahkan

$ python do-my-stuff.py < infile.txt

Yang akan membuat anda Python script berperilaku seperti banyak GNU/Unix program-program seperti kucing, grep dan sed.

Komentar (0)

argparse adalah solusi yang mudah

Contoh kompatibel dengan Python versi 2 dan 3:

#!/usr/bin/python

import argparse
import sys

parser = argparse.ArgumentParser()

parser.add_argument('infile',
                    default=sys.stdin,
                    type=argparse.FileType('r'),
                    nargs='?')

args = parser.parse_args()

data = args.infile.read()

Anda dapat menjalankan script ini dalam banyak cara:

1. Menggunakan stdin

echo 'foo bar' | ./above-script.py

  atau lebih pendek dengan mengganti echo oleh di sini string:


./above-script.py 
Komentar (3)

Chip berikut kode yang akan membantu anda (ini akan membaca semua dari stdin pemblokiran kepada EOF, menjadi satu string):

import sys
input_str = sys.stdin.read()
print input_str.split()
Komentar (0)

Coba ini:

import sys

print sys.stdin.read().upper()

dan cek dengan:

$ echo "Hello World" | python myFile.py
Komentar (0)

Anda bisa baca dari stdin dan kemudian menyimpan input ke "data" sebagai berikut:

data = ""
for line in sys.stdin:
    data += line
Komentar (2)

Baca dari sys.stdin, tapi untuk membaca data biner pada Windows, anda perlu ekstra hati-hati, karena sys.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.

import sys

PY3K = sys.version_info >= (3, 0)

if PY3K:
    source = sys.stdin.buffer
else:
    # Python 2 on Windows opens sys.stdin in text mode, and
    # binary data that read from it becomes corrupted on \r\n
    if sys.platform == "win32":
        # set sys.stdin to binary mode
        import os, msvcrt
        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    source = sys.stdin

b = source.read()
Komentar (0)

Saya cukup kagum tidak ada yang telah disebutkan hack ini sejauh ini:

python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"

kompatibel dengan kedua python2 dan python3

Komentar (1)

Masalah yang saya miliki dengan solusi

import sys

for line in sys.stdin:
    print(line)

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:

import sys
import select

# select(files to read from, files to write to, magic, timeout)
# timeout=0.0 is essential b/c we want to know the asnwer right away
if select.select([sys.stdin], [], [], 0.0)[0]:
    help_file_fragment = sys.stdin.read()
else:
    print("No data passed to stdin", file=sys.stderr)
    sys.exit(2)
Komentar (2)

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)

import sys, os
sep=os.linesep

while sep == os.linesep:
    data = sys.stdin.readline()               
    sep = data[-len(os.linesep):]
    print '> "%s"' % data.strip()

Jadi jika anda mulai mendengarkan pada soket ini akan bekerja dengan baik (misalnya di bash):

while :; do nc -l 12345 | python test.py ; done

Dan anda bisa menyebutnya dengan telnet atau hanya mengarahkan browser ke localhost:12345

Komentar (0)

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):

with open(sys.argv[1], 'r') as f:
    for line in f:

Kemudian saya dapat menjalankan script secara lokal sebagai:

python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work
Komentar (4)

Untuk Python 3 yang akan sama:

# Filename e.g. cat.py
import sys

for line in sys.stdin:
    print(line, end="")

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:

echo Hello | ./cat.py
Komentar (0)

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()

Komentar (0)