Cum ai citit de la intrarea standard?

Am'm încercarea de a face unele de cod de golf provocări, dar toate acestea necesită o intrare să fie luate de la stdin`. Cum a face I a lua că în Python?

Ai putea folosi fileinput modulul:

import fileinput

for line in fileinput.input():
    pass

fileinput va bucla prin toate liniile de intrare specificat ca nume de fișier dat în argumente în linia de comandă, sau standard de intrare dacă nu argumentele sunt furnizate.

Notă: "de linie" va conține un trailing newline; să scoateți-l folosesc linie.rstrip()`

Comentarii (1)

Nu's câteva modalități de a face asta.

  • sys.stdin este un fișier obiect pe care puteți apela funcții de citire " sau " readlines dacă doriți să citiți totul sau doriți să citiți totul și să-l împartă prin newline automat. (Trebuie să import sys pentru ca aceasta să funcționeze.)

  • Dacă vrei să prompt utilizatorul pentru intrare, puteți utiliza raw_input în Python 2.X, și doar input în Python 3.

  • Dacă tu de fapt vrei doar să citești opțiuni de linie de comandă, le puteți accesa prin intermediul sys.argv lista.

Veți găsi, probabil, acest Wikibook articolul pe I/O în Python pentru a fi o referință utilă, precum și.

Comentarii (0)

``pyton import sys

pentru linia în sys.stdin: print(linie) ``

Rețineți că acest lucru va include un caracter newline la sfarsit. Pentru a elimina newline la sfarsit, foloseste-line.rstrip()` ca @brittohalloran spus.

Comentarii (4)

Python are, de asemenea, built-in functii input () " și " raw_input(). Vezi Python documentație sub Built-in Functii.

De exemplu,

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

sau

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

Aici's de Învățare Python:

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

Pe Unix, ai putea încercare de a face ceva de genul:

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

Pe Windows sau DOS, ai'd face:

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

Răspunsul propus de către alții:

for line in sys.stdin:
  print line

este foarte simplu și pythonic, dar trebuie să se constate că script-ul va aștepta până când EOF înainte de a începe pentru a repeta pe liniile de intrare.

Acest lucru înseamnă că tail-f error_log | myscript.py nu va procesa liniile cum era de așteptat.

Scriptul corect pentru un astfel de caz de utilizare ar fi:

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

    if not line:
        break

    print line

UPDATE Din comentarii s-a lămurit că pe pitonul 2 numai acolo ar putea fi tamponare implicate, astfel încât să se încheie în așteptare pentru tampon pentru a umple sau EOF înainte de imprimare apel este emis.

Comentarii (7)

Cum ai citit de la intrarea standard în Python?

nu'm încercat să fac parte din codul de golf provocări, dar toate acestea necesită o intrare să fie luate de la stdin. Cum a face I a lua că în Python? Puteți folosi:

  • sys.stdin - Un fișier-ca obiect - spune-sys.stdin.read()` pentru a citi totul.
  • input(prompt) - trece un opțional prompt la ieșire, se citește de la intrarea standard până la prima linie nouă, care-l fâșii. Te'd trebuie să faci acest lucru în mod repetat pentru a obține mai multe linii, la sfârșitul de intrare se ridică EOFError. (Probabil nu foarte bun pentru golf.) În Python 2, e rawinput(prompt).
  • deschis(0).read() - În Python 3, built-in funcția "open" acceptă descriptorii de fișier (numere întregi reprezentând sistemul de operare IO resurse), iar 0 este descriptorul de stdin. Returnează un fișier obiect ca ca sys.stdin - probabil cel mai bun pariu pentru golf. În Python 2, aceasta este io.deschide.
  • deschise('/dev/stdin').read()- similare cuopen(0)`, funcționează pe Python 2 și 3, dar nu pe Windows (sau chiar Cygwin).
  • fileinput.de intrare() - returnează un iterator peste linii în toate fișierele listate în sys.argv[1:], sau stdin dacă nu a dat. Utilizarea ca''.alăturați-vă(fileinput.de intrare()). Ambele sys și fileinput trebuie să fie importate, respectiv, desigur.

    Repede sys.stdin exemple compatibil cu Python 2 și 3, Windows, Unix

    Ai nevoie doar de a "citi" de la sys.stdin, de exemplu, dacă conductei de date de la intrarea standard:

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

Putem vedea că sys.stdin este în mod implicit modul text: ``python

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

fișier exemplu

Spune că ai un fișier, inputs.txt putem accepta acel fișier și scrie pe spate:

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

Mai răspunde

Aici's-o complet, ușor de reprodus, demo, folosind două metode, în funcție nativă, "intrare" (folosesc raw_input în Python 2), sys.stdin. Datele sunt nemodificate, deci prelucrarea este un non-operare. Pentru a începe cu, las's a crea un fișier pentru intrări:

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

Și folosind codul de ne'am văzut deja, putem verifica faptul că ne-am'am creat fișierul:

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

Aici's a ajuta pe `sys.stdin.citesc de 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.

Interna functia de "intrare" (`raw_input în Python 2)

Interna funcția de "intrare" se citește de la intrarea standard până la o linie nouă, care este deposedat (completând "imprimare", care adaugă o linie nouă în mod implicit.) Acest lucru se întâmplă până când acesta devine EOF (Sfârșit De Fișier), moment în care se ridică EOFError. Astfel, aici's cum puteți folosi "intrare" în Python 3 (sau `raw_input în Python 2) pentru a citi de la intrarea standard - deci, vom crea un modul Python numim stdindemo.py:

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

Și să's de imprimare înapoi pentru a se asigura că's cum ne asteptam:

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

Din nou, "intrare" citește până la newline și, în esență, benzi de linie. "imprimare" adaugă o linie nouă. Deci, în timp ce amândoi modifica intrare, modificările lor anula. (Astfel încât acestea sunt, în esență, reciproc's complement.) Și atunci când "input" devine end-of-file de caracter, se ridică EOFError, care ne ignora și apoi de ieșire din program. Și pe Linux/Unix, putem conducta de pisica:

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

Sau putem redirecționa fișierul de la stdin:

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

Putem executa, de asemenea, la modul ca un script:

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

Aici's a ajuta pe comanda interna "intrare" la 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

Aici vom face un script demo folosind sys.stdin. Eficient mod de a itera peste un fișier obiect este de a folosi file-ca obiect, ca un iterator. Complementar metoda de a scrie la stdout de la această intrare este de a folosi pur și simplu `sys.stdout.scrie:

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

Imprimați-l înapoi pentru a vă asigura că arată bine:

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

Și redirecționarea intrărilor în fișier:

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

Jucăm într-o comandă:

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

Descriptorii de fișier pentru Golf

Deoarece descriptorii de fișier pentru stdin " și "stdout` sunt 0 și 1, respectiv, putem trece, de asemenea, cei de la "open" în Python 3 (nu 2, și rețineți că avem nevoie în continuare de 'g' pentru a scrie la stdout). Dacă acesta funcționează pe sistemul dumneavoastră, acesta va rade de pe mai multe caractere.

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

Python 2's io.deschide face asta la fel de bine, dar de import nevoie de mai mult spațiu:

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

Pentru a aborda alte comentarii și răspunsuri

Un comentariu sugerează&#39;&#39;.alăturați-vă(sys.stdin) pentru golf dar care&#39;s, de fapt, mai mult decât sys.stdin.read() - plus Python trebuie să creeze un plus de listă în memorie (ca&#39;cum sstr.alături de lucrări atunci când nu a dat o listă) - pentru contrast:

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

Răspunsul de sus sugerează:

import fileinput

for line in fileinput.input():
    pass

Dar, din sys.stdin implementează fișierul API, inclusiv iterator protocol, care's la fel ca asta:

import sys

for line in sys.stdin:
    pass

Un alt răspuns nu sugera acest lucru. Doar amintiți-vă că, dacă o faci într-un interpret, ai'll nevoie pentru a face Ctrl-: d daca're pe Linux sau Mac, sau Ctrl-z pe Windows (după Enter) pentru a trimite end-of-file caracter la proces. De asemenea, acest răspuns sugerează print(linie) - care adaugă un &#39;\n&#39; la finalprint(linie, end='')în loc (în cazul în Python 2,&#39;ll nevoie de __viitoarele__ import print_function). Adevărata caz de utilizare pentru fileinput` este pentru lectură într-o serie de fișiere.

Comentarii (0)

Acest lucru va echo intrarea standard la ieșirea standard:

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

Clădirea de pe toate anwers folosind `sys.stdin, puteți face, de asemenea, ceva de genul următor pentru a citi de la un argument de fișier dacă cel puțin un argument există, și cad înapoi la stdin altfel:

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

și de a folosi ca nici

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

sau

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

sau chiar

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

Asta ar face Python script-ul se comporta la fel ca multe GNU/Unix programe, cum ar fi "pisică", grep și sed.

Comentarii (0)

argparse este o soluție ușor

Exemplu compatibil cu versiunile Python 2 și 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()

Puteți rula acest script în mai multe moduri:

1. Folosind stdin

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

  sau mai scurte prin înlocuirea "echo", de aici string:


./above-script.py 
Comentarii (3)

Următoarele chip de cod vă va ajuta să (se va citi toate stdin blocarea către EOF, într-un singur șir de caractere):

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

Încercați acest lucru:

import sys

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

și verificați-l cu:

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

Puteți citi de la intrarea standard și apoi depozitați-intrări în "de date" după cum urmează:

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

Citiți din sys.stdin, dar la citește date binare pe Windows, trebuie să fie foarte atenți, pentru că sys.stdin nu este deschis în mod text și nu va corupt \r\n înlocuirea lor cu \n.

Soluția este de a stabili modul în binar dacă Windows + Python 2 este detectat, și pe Python 3 utilizarea 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()
Comentarii (0)

Sunt destul de uimit nimeni nu a menționat acest hack de până acum:

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

compatibil atât cu python2 și python3

Comentarii (1)

Problema pe care o am cu soluție

import sys

for line in sys.stdin:
    print(line)

este că, dacă nu't trece orice date de la intrarea standard, se va bloca pentru totdeauna. Ca's de ce-mi place acest răspuns: verificați dacă există unele date de pe stdin în primul rând, și apoi a citit-o. Aceasta este ceea ce am ajuns să fac:

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

Am avut unele probleme atunci când obtinerea de acest lucru pentru lectură peste prize adus la ea. Atunci când priza a fost închis, a început revenirea șir gol într-un activ curent. Deci, aceasta este soluția mea la aceasta (pe care am testat doar in linux, dar sper că funcționează în toate celelalte sisteme)

import sys, os
sep=os.linesep

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

Deci, dacă începi să asculți pe un soclu se va lucra în mod corespunzător (de exemplu, în bash):

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

Și puteți apela cu telnet sau doar punct un browser pentru a localhost:12345

Comentarii (0)

Cu privire la acest lucru:

pentru linie în sys.stdin:

Am încercat pe python 2.7 (următoarele altcineva's sugestie) pentru un fișier foarte mare, și eu nu't-l recomand, tocmai pentru motivele menționate mai sus (nimic nu se întâmplă pentru o lungă perioadă de timp).

Am ajuns cu puțin mai pythonic soluție (și funcționează pe fișiere mai mari):

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

Atunci pot rula script-ul local ca:

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

Pentru Python 3 ar fi:

# Filename e.g. cat.py
import sys

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

Aceasta este de fapt o formă simplă de pisica(1), de't a adăuga o linie nouă după fiecare linie. Puteți folosi acest lucru (dupa ce a marcat fișier executabil folosind chmod +x cat.py cum ar fi:

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

Există os.citit(0, x) care citește xbytes de la 0, care reprezintă stdin. Aceasta este o unbuffered citit, mai scăzut nivel decât sys.stdin.read()

Comentarii (0)