Làm thế nào để bạn đọc từ stdin?


1472

Tôi đang cố gắng thực hiện một số thử thách golf mã , nhưng tất cả chúng đều yêu cầu đầu vào phải được lấy từ đó stdin. Làm thế nào để tôi có được điều đó trong Python?

Câu trả lời:


950

Bạn có thể sử dụng fileinputmô-đun:

import fileinput

for line in fileinput.input():
    pass

fileinput sẽ lặp qua tất cả các dòng trong đầu vào được chỉ định dưới dạng tên tệp được đưa ra trong các đối số dòng lệnh hoặc đầu vào tiêu chuẩn nếu không có đối số nào được cung cấp.

Lưu ý: linesẽ chứa một dòng mới; để loại bỏ nó sử dụngline.rstrip()


1
@BorislavStoilov Và câu trả lời này không trả lời đúng câu hỏi: "hoặc đầu vào tiêu chuẩn nếu không có đối số nào được cung cấp".
Dietmar

1
Tài liệu nói rằng nó dự phòng cho stdin: "Điều này lặp lại qua các dòng của tất cả các tệp được liệt kê trong sys.argv [1:], mặc định là sys.stdin nếu danh sách trống. Nếu tên tệp là '-', nó cũng được thay thế bởi sys.stdin. Để chỉ định một danh sách tên tệp thay thế, hãy chuyển nó làm đối số đầu tiên cho input (). Một tên tệp duy nhất cũng được cho phép. "
Arlo

721

Có một vài cách để làm điều đó.

  • sys.stdinlà một đối tượng giống như tệp mà bạn có thể gọi các hàm readhoặc readlinesnếu bạn muốn đọc mọi thứ hoặc bạn muốn đọc mọi thứ và tự động phân tách nó theo dòng mới. (Bạn cần import sysđể làm việc này.)

  • Nếu bạn muốn nhắc người dùng nhập liệu, bạn có thể sử dụng raw_inputtrong Python 2.X và chỉ inputtrong Python 3.

  • Nếu bạn thực sự chỉ muốn đọc các tùy chọn dòng lệnh, bạn có thể truy cập chúng thông qua danh sách sys.argv .

Bạn có thể sẽ thấy bài viết Wikibook này về I / O trong Python là một tài liệu tham khảo hữu ích.


445
import sys

for line in sys.stdin:
    print(line)

Lưu ý rằng điều này sẽ bao gồm một ký tự dòng mới ở cuối. Để xóa dòng mới ở cuối, hãy sử dụng line.rstrip()như @brittohalloran nói.


7
line.rstrip ('\ n'), nếu không, nó sẽ xóa tất cả các khoảng trắng
avp

sử dụng phương pháp này, làm thế nào để chúng ta biết khi nào luồng đầu vào kết thúc? Tôi muốn thêm dấu phẩy sau mỗi dòng excepts cho dòng cuối cùng.
nghiện

Tôi nhận được: TypeError: đối tượng 'FileWrapper' không thể lặp lại.
Diego Queiroz

@avp điều này sẽ không giải quyết chính xác với \r\nkết thúc dòng
josch

228

Python cũng có các hàm dựng sẵn input()raw_input(). Xem tài liệu Python dưới Hàm dựng sẵn .

Ví dụ,

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

hoặc là

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

7
Điều này đọc một dòng duy nhất, đó không thực sự là những gì OP yêu cầu. Tôi diễn giải câu hỏi là "làm thế nào để tôi đọc một loạt các dòng từ một tệp xử lý mở cho đến EOF?"
tripleee

4
OP không yêu cầu đọc đầu vào từ bàn phím, Anh ấy yêu cầu đọc từ stdin mà trong tình huống dự thi thường được cung cấp cho các thí sinh.
chrisfs

đây là những gì tôi cần, google đưa tôi đến đây thú vị là tôi đã quản lý để mã các thẻ rfid, datetime, cơ sở dữ liệu, nhưng không bao giờ bận tâm đọc đầu vào từ người dùng lol
clockw0rk

204

Đây là từ Học Python :

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

Trên Unix, bạn có thể kiểm tra nó bằng cách thực hiện một số thứ như:

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

Trên Windows hoặc DOS, bạn sẽ làm:

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

4
Đây là cách hiệu quả hơn về bộ nhớ (và có thể nhanh hơn) để đếm các dòng trong Python : print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 << 15), ''))). xemwc-l.py
jfs

11
Việc sử dụng catở đây là dư thừa. Yêu cầu chính xác cho các hệ thống Unix là python countlines.py < countlines.py.
istepaniuk

12
"Học Python" là sai khi hướng người dùng sử dụng readlines(). Các đối tượng tệp được dự định lặp đi lặp lại mà không cụ thể hóa tất cả dữ liệu trong bộ nhớ.
Aaron Hall

118

Làm thế nào để bạn đọc từ stdin trong Python?

Tôi đang cố gắng thực hiện một số thử thách golf mã, nhưng tất cả chúng đều yêu cầu đầu vào phải được lấy từ stdin. Làm thế nào để tôi có được điều đó trong Python?

Bạn có thể dùng:

  • sys.stdin- Một đối tượng giống như tệp - gọi sys.stdin.read()để đọc mọi thứ.
  • input(prompt)- chuyển cho nó một dấu nhắc tùy chọn để xuất ra, nó đọc từ stdin cho đến dòng mới đầu tiên, nó thoát ra. Bạn sẽ phải làm điều này nhiều lần để có được nhiều dòng hơn, vào cuối đầu vào, nó sẽ tăng EOFError. (Có lẽ không tuyệt vời cho việc chơi gôn.) Trong Python 2, đây là rawinput(prompt).
  • open(0).read()- Trong Python 3, hàm dựng sẵn openchấp nhận bộ mô tả tệp (số nguyên biểu thị tài nguyên IO của hệ điều hành) và 0 là bộ mô tả của stdin. Nó trả về một đối tượng giống như tệp sys.stdin- có lẽ là đặt cược tốt nhất của bạn để chơi gôn. Trong Python 2, đây là io.open.
  • open('/dev/stdin').read()- tương tự open(0), hoạt động trên Python 2 và 3, nhưng không hoạt động trên Windows (hoặc thậm chí Cygwin).
  • fileinput.input()- trả về một trình vòng lặp qua các dòng trong tất cả các tệp được liệt kê trong sys.argv[1:]hoặc stdin nếu không được cung cấp. Sử dụng như thế nào ''.join(fileinput.input()).

Tất cả sysfileinputphải được nhập khẩu, tương ứng, tất nhiên.

Các sys.stdinví dụ nhanh tương thích với Python 2 và 3, Windows, Unix

Bạn chỉ cần readtừ sys.stdin, ví dụ, nếu bạn chuyển dữ liệu sang stdin:

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

Chúng ta có thể thấy đó sys.stdinlà trong chế độ văn bản mặc định:

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

ví dụ tập tin

Giả sử bạn có một tệp, inputs.txtchúng tôi có thể chấp nhận tệp đó và viết lại:

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

Câu trả lời dài hơn

Đây là một bản demo hoàn chỉnh, có thể sao chép dễ dàng, sử dụng hai phương thức, hàm dựng sẵn, input(sử dụng raw_inputtrong Python 2) và sys.stdin. Dữ liệu không được sửa đổi, vì vậy việc xử lý là không hoạt động.

Để bắt đầu, hãy tạo một tệp cho đầu vào:

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

Và bằng cách sử dụng mã chúng ta đã thấy, chúng ta có thể kiểm tra xem chúng ta đã tạo tệp chưa:

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

Đây là sự trợ giúp sys.stdin.readtừ 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.

Hàm dựng sẵn, input( raw_inputtrong Python 2)

Hàm dựng sẵn inputđọc từ đầu vào tiêu chuẩn cho đến một dòng mới, được loại bỏ (bổ sung print, thêm một dòng mới theo mặc định.) Điều này xảy ra cho đến khi nó nhận được EOF (End Of File), tại đó nó tăng lên EOFError.

Vì vậy, đây là cách bạn có thể sử dụng inputtrong Python 3 (hoặc raw_inputtrong Python 2) để đọc từ stdin - vì vậy chúng tôi tạo một mô-đun Python mà chúng tôi gọi là stdindemo.py:

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

Và hãy in nó ra để đảm bảo nó như chúng ta mong đợi:

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

Một lần nữa, inputđọc lên cho đến dòng mới và về cơ bản tước nó khỏi dòng. printthêm một dòng mới. Vì vậy, trong khi cả hai đều sửa đổi đầu vào, sửa đổi của họ hủy bỏ. (Vì vậy, về cơ bản chúng là bổ sung cho nhau.)

Và khi inputnhận được ký tự cuối tệp, nó sẽ tăng EOFError, cái mà chúng ta bỏ qua và sau đó thoát khỏi chương trình.

Và trên Linux / Unix, chúng ta có thể chuyển từ mèo:

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

Hoặc chúng ta chỉ có thể chuyển hướng tệp từ stdin:

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

Chúng tôi cũng có thể thực thi mô-đun như một kịch bản:

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

Đây là trợ giúp về nội dung inputtừ 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

Ở đây chúng tôi tạo một kịch bản demo bằng cách sử dụng sys.stdin. Cách hiệu quả để lặp lại một đối tượng giống như tệp là sử dụng đối tượng giống như tệp làm trình vòng lặp. Phương pháp bổ sung để ghi vào thiết bị xuất chuẩn từ đầu vào này chỉ đơn giản là sử dụng sys.stdout.write:

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

In nó ra để đảm bảo nó trông đúng:

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

Và chuyển hướng đầu vào vào tập tin:

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

Chơi gôn thành một lệnh:

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

Mô tả tập tin để chơi gôn

Vì các mô tả tệp cho stdinstdoutlần lượt là 0 và 1, chúng ta cũng có thể chuyển chúng cho openPython 3 (không phải 2 và lưu ý rằng chúng ta vẫn cần 'w' để ghi vào thiết bị xuất chuẩn).

Nếu điều này hoạt động trên hệ thống của bạn, nó sẽ loại bỏ nhiều ký tự hơn.

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

Python 2 cũng io.openlàm điều này, nhưng quá trình nhập chiếm nhiều không gian hơn:

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

Giải quyết các ý kiến ​​và câu trả lời khác

Một nhận xét gợi ý ''.join(sys.stdin)cho việc chơi golf nhưng thực sự dài hơn sys.stdin.read () - cộng với Python phải tạo thêm một danh sách trong bộ nhớ (đó là cách str.joinhoạt động khi không được đưa ra danh sách) - ngược lại:

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

Câu trả lời hàng đầu cho thấy:

import fileinput

for line in fileinput.input():
    pass

Nhưng, vì sys.stdintriển khai API tệp, bao gồm cả giao thức iterator, điều đó cũng giống như sau:

import sys

for line in sys.stdin:
    pass

Câu trả lời khác không đề nghị này. Chỉ cần nhớ rằng nếu bạn làm điều đó trong một trình thông dịch, bạn sẽ cần phải làm Ctrl- dnếu bạn đang dùng Linux hoặc Mac hoặc Ctrl- ztrên Windows (sau Enter) để gửi ký tự cuối tệp đến quy trình. Ngoài ra, câu trả lời đó cho thấy print(line)- bổ sung thêm '\n'vào cuối - sử dụng print(line, end='')thay thế (nếu trong Python 2, bạn sẽ cần from __future__ import print_function).

Trường hợp sử dụng thực tế fileinputlà để đọc trong một loạt các tệp.


103

Câu trả lời được đề xuất bởi người khác:

for line in sys.stdin:
  print line

là rất đơn giản và pythonic, nhưng phải lưu ý rằng tập lệnh sẽ đợi cho đến khi EOF trước khi bắt đầu lặp lại trên các dòng đầu vào.

Điều này có nghĩa là tail -f error_log | myscript.pysẽ không xử lý các dòng như mong đợi.

Kịch bản chính xác cho trường hợp sử dụng như vậy sẽ là:

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

    if not line:
        break

    print line

CẬP NHẬT
Từ các bình luận đã bị xóa rằng trên python 2 chỉ có thể có bộ đệm liên quan, do đó cuối cùng bạn chờ đợi bộ đệm điền hoặc EOF trước khi lệnh in được phát ra.


8
Các for line in sys.stdin:mẫu không chờ EOF. Nhưng nếu bạn kiểm tra trên các tệp rất nhỏ, các phản hồi có thể bị đệm. Kiểm tra với nhiều dữ liệu hơn để thấy rằng nó đọc kết quả trung gian.
mb.

Tôi chờ đợi End Of File hoặc bộ đệm, khi lấy đầu vào từ luồng khi sử dụng python 2.6.6, nhưng với 3.1.3 thì không. Lưu ý print linekhông đánh thức trong 3.1.3, nhưng print(line)không.
ctrl-alt-delor

python của tôi 2.7.5 "cho dòng trong sys.stdin", chặn cho đến EOF hoặc một lượng dữ liệu hợp lý đã được đệm. Phạt cho xử lý luồng. Không tốt cho xử lý từng dòng hoặc đầu vào của người dùng.
Sean

2
Tôi nghi ngờ điều này có liên quan đến việc phát hiện tty trong libc, vì vậy khi bạn phát hiện ra nó trên vỏ tương tác, nó sẽ không phát hiện ra tty nào, unbuffer từ kỳ vọng-dev là một tiện ích hữu ích mà tôi tin rằng việc tiêm shim qua ld_preload vì vậy is_atty trả về đúng nghi ngờ đó là cách nó đang trao nó)
Mâtt Frëëman

8
@Sean: sai rồi . for line in sys.stdin:không "chặn cho đến EOF". Có một lỗi đọc trước trong Python 2 làm trì hoãn các dòng cho đến khi bộ đệm tương ứng đầy. Đây là một vấn đề đệm không liên quan đến EOF. Để giải quyết, sử dụng for line in iter(sys.stdin.readline, ''):(sử dụng io.open()cho các tệp thông thường). Bạn không cần nó trong Python 3.
jfs

39

Điều này sẽ lặp lại đầu vào tiêu chuẩn thành đầu ra tiêu chuẩn:

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

31

Dựa trên tất cả các anwers đang sử dụng sys.stdin, bạn cũng có thể thực hiện một số thao tác như sau để đọc từ tệp đối số nếu có ít nhất một đối số tồn tại và quay lại stdin nếu không:

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

và sử dụng nó như là một trong hai

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

hoặc là

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

hoặc thậm chí

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

Điều đó sẽ làm cho tập lệnh Python của bạn hoạt động giống như nhiều chương trình GNU / Unix như cat , grepsed.


17

argparse là một giải pháp dễ dàng

Ví dụ tương thích với cả hai phiên bản Python 2 và 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()

Bạn có thể chạy tập lệnh này theo nhiều cách:

1. Sử dụng stdin

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

  hoặc ngắn hơn bằng cách thay thế echobằng chuỗi ở đây :

./above-script.py <<< 'foo bar'

2. Sử dụng đối số tên tệp

echo 'foo bar' > my-file.data
./above-script.py my-file.data

3. Sử dụng stdinthông qua tên tệp đặc biệt-

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

Dưới đây là câu trả lời về những việc cần làm, nếu tệp đầu vào được nén: stackoverflow.com/a/33621549/778533 Người ta cũng có thể làm add_argument('--in'và sau đó chuyển sang tập lệnh và thêm --in -vào dòng lệnh. PS inkhông phải là một tên rất tốt cho một biến / thuộc tính.
tommy.carstensen

inkhông chỉ là một tên xấu cho một biến, nó là bất hợp pháp. args.in.read()sẽ đưa ra lỗi UnlimitedSyntax vì intừ khóa dành riêng. Chỉ đơn giản là có thể đổi tên cho infilegiống như python argparse tài liệu làm: docs.python.org/3/library/...
Ken Colton

Cảm ơn bạn @ tommy.carstensen vì phản hồi của bạn, tôi vừa cải thiện câu trả lời. Giáng sinh vui vẻ và năm mới hạnh phúc ;-)
olibre 27/12/18

14

Đoạn mã sau đây sẽ giúp bạn (nó sẽ đọc tất cả các stdin chặn cho đến EOFmột chuỗi):

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

8

Tôi khá ngạc nhiên khi không có ai đề cập đến vụ hack này cho đến nay:

python -c "import sys; set(map(sys.stdout.write,sys.stdin))"

trong python2 bạn có thể bỏ set()cuộc gọi, nhưng nó sẽ chuyển từ


1
Tại sao sử dụng readlinesphân chia thành dòng và sau đó joinmột lần nữa? Bạn chỉ có thể viếtprint(sys.stdin.read())
musiphil

Điều này sẽ sử dụng nhiều bộ nhớ hơn mức cần thiết vì python cần xây dựng một mảng bổ sung.
Harry Moreno

Chà, thật ra thì không, vì writelợi nhuận Nonevà kích thước đã đặt sẽ không bao giờ lớn hơn 1 ( =len(set([None])))
Uri Goren

7

Thử cái này:

import sys

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

và kiểm tra nó với:

$ echo "Hello World" | python myFile.py

7

Bạn có thể đọc từ stdin và sau đó lưu trữ dữ liệu vào "dữ liệu" như sau:

data = ""
for line in sys.stdin:
    data += line


Điều tương tự có thể được thực hiện với data = sys.stdin.read(), mà không có vấn đề nối chuỗi lặp lại.
musiphil

6

Đọc từ sys.stdin, nhưng để đọc dữ liệu nhị phân trên Windows , bạn cần hết sức cẩn thận, vì sys.stdinđã mở ở chế độ văn bản và nó sẽ bị hỏng \r\nthay thế chúng bằng \n.

Giải pháp là đặt chế độ thành nhị phân nếu phát hiện Windows + Python 2 và trên Python 3 sử dụng 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()

4

Tôi sử dụng phương thức sau, nó trả về một chuỗi từ stdin (Tôi sử dụng nó để phân tích cú pháp json). Nó hoạt động với pipe và prompt trên Windows (chưa được thử nghiệm trên Linux). Khi nhắc, hai ngắt dòng cho biết kết thúc đầu vào.

def get_from_stdin():

  lb = 0
  stdin = ''

  for line in sys.stdin:
    if line == "\n":
        lb += 1
        if lb == 2:
            break
    else:
        lb = 0
        stdin += line

  return stdin

3

Vấn đề tôi có với giải pháp

import sys

for line in sys.stdin:
    print(line)

là nếu bạn không chuyển bất kỳ dữ liệu nào cho stdin, nó sẽ bị chặn vĩnh viễn. Đó là lý do tại sao tôi thích câu trả lời này : kiểm tra xem có dữ liệu nào về stdin trước không, sau đó đọc nó. Đây là những gì tôi đã làm:

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)

Tôi thực sự khuyên bạn nên che giấu điều đáng ghét này nếu điều kiện thành một phương pháp mặc dù.
tiktak

1
Phương pháp này giới hạn khả năng ứng dụng của chương trình một cách nghiêm túc: ví dụ: bạn không thể sử dụng phương thức này cho đầu vào tương tác từ thiết bị đầu cuối, bởi vì đầu vào sẽ gần như không bao giờ "sẵn sàng" khi selectđược gọi; hoặc bạn cũng có thể gặp vấn đề nếu stdin được kết nối với một tệp trên phương tiện chậm (mạng, CD, băng, v.v.). Bạn nói rằng "nếu bạn không chuyển bất kỳ dữ liệu nào cho stdin, nó sẽ bị chặn vĩnh viễn." là một vấn đề , nhưng tôi sẽ nói đó là một tính năng . Hầu hết các chương trình CLI (ví dụ cat) hoạt động theo cách này và chúng được mong đợi. EOF là điều duy nhất bạn nên phụ thuộc vào để phát hiện kết thúc của đầu vào.
musiphil

2

Tôi đã có một số vấn đề khi làm cho nó hoạt động để đọc qua các ổ cắm được dẫn đến nó. Khi ổ cắm đã đóng, nó bắt đầu trả về chuỗi rỗng trong một vòng lặp hoạt động. Vì vậy, đây là giải pháp của tôi cho nó (mà tôi chỉ thử nghiệm trong linux, nhưng hy vọng nó hoạt động trong tất cả các hệ thống khác)

import sys, os
sep=os.linesep

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

Vì vậy, nếu bạn bắt đầu nghe trên một ổ cắm, nó sẽ hoạt động bình thường (ví dụ như trong bash):

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

Và bạn có thể gọi nó bằng telnet hoặc chỉ một trình duyệt tới localhost: 12345


1

Về vấn đề này:

for line in sys.stdin:

Tôi vừa thử nó trên python 2.7 (theo gợi ý của người khác) cho một tệp rất lớn và tôi không khuyên dùng nó, chính xác là vì những lý do được đề cập ở trên (không có gì xảy ra trong một thời gian dài).

Tôi đã kết thúc với một giải pháp pythonic hơn một chút (và nó hoạt động trên các tệp lớn hơn):

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

Sau đó, tôi có thể chạy tập lệnh cục bộ như:

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

Mở một tập tin không phải là đọc từ stdin, giống như câu hỏi. -1
Aaron Hall

Trong trường hợp này, tôi chuyển vào sys.stdindưới dạng đối số dòng lệnh cho tập lệnh.
szeitlin

1
Làm thế nào bạn có thể vượt qua sys.stdinnhư là một đối số dòng lệnh cho kịch bản? Đối số là chuỗi và luồng là các đối tượng giống như tệp, chúng không giống nhau.
DeFazer

@DeFazer chỉnh sửa để hiển thị cách sử dụng nó. Các đối số là các chuỗi, vâng, nhưng như các tài liệu python và tôi đã đề cập trong một nhận xét trước đó ở trên,sys.stdin là một đối tượng giống như tệp
szeitlin

1

Đối với Python 3 , đó sẽ là:

# Filename e.g. cat.py
import sys

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

Về cơ bản, đây là một dạng mèo đơn giản (1), vì nó không thêm dòng mới sau mỗi dòng. Bạn có thể sử dụng điều này (sau khi Bạn đã đánh dấu tệp thực thi bằng cách sử dụng, chmod +x cat.pychẳng hạn như:

echo Hello | ./cat.py

0

os.read(0, x) đọc xbyte từ 0 đại diện cho stdin. Đây là một lần đọc không có bộ đệm, mức độ thấp hơn so với sys.stdin.read ()


0

Khi sử dụng -clệnh, như một cách khó khăn, thay vì đọc stdin(và linh hoạt hơn trong một số trường hợp), bạn có thể truyền lệnh shell shell cho lệnh python của mình bằng cách đặt lệnh sell trong dấu ngoặc đơn trong dấu ngoặc đơn bắt đầu bằng $dấu.

ví dụ

python3 -c "import sys; print(len(sys.argv[1].split('\n')))" "$(cat ~/.goldendict/history)"

Điều này sẽ đếm số lượng dòng từ tệp lịch sử của goldendict.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.