Hướng dẫn sys.stdin python - trăn sys.stdin

Vì vậy, bạn đã sử dụng "các hàm được tích hợp sẵn" của Python, có lẽ như thế này:

file_object = open('filename')
for something in file_object:
    some stuff here

Thao tác này đọc tệp bằng cách gọi một trình lặp trên đối tượng tệp sẽ trả về dòng tiếp theo từ tệp.

Thay vào đó, bạn có thể sử dụng:

file_object = open('filename')
lines = file_object.readlines()

mà đọc các dòng từ vị trí tệp hiện tại vào một danh sách.

Bây giờ,

file_object = open('filename')
lines = file_object.readlines()
2chỉ là một đối tượng tệp khác, sẽ được Python mở trước khi chương trình của bạn bắt đầu. Những gì bạn làm với đối tượng tệp đó là tùy thuộc vào bạn, nhưng nó không thực sự khác biệt với bất kỳ đối tượng tệp nào khác, chỉ là bạn không cần một đối tượng tệp
file_object = open('filename')
lines = file_object.readlines()
3.

for something in sys.stdin:
    some stuff here

sẽ lặp lại thông qua đầu vào chuẩn cho đến khi đạt đến phần cuối của tệp. Và điều này cũng vậy:

lines = sys.stdin.readlines()

Câu hỏi đầu tiên của bạn thực sự là về các cách khác nhau để sử dụng một đối tượng tệp.

Thứ hai, nó được đọc từ đâu? Nó đang đọc từ bộ mô tả tệp 0 (không). Trên Windows, nó là tệp xử lý 0 (không). Bộ mô tả tệp / tay cầm 0 được kết nối với bảng điều khiển hoặc tty theo mặc định, do đó, trên thực tế, nó đang đọc từ bàn phím. Tuy nhiên, nó có thể được chuyển hướng , thường bằng một shell (như bash hoặc cmd.exe) bằng cách sử dụng cú pháp như sau:

myprog.py < input_file.txt 

Điều đó làm thay đổi bộ mô tả tệp bằng không để đọc tệp thay vì bàn phím. Trên UNIX hoặc Linux, điều này sử dụng lệnh gọi cơ bản

file_object = open('filename')
lines = file_object.readlines()
4. Đọc tài liệu trình bao của bạn để biết thêm thông tin về chuyển hướng (hoặc có thể
file_object = open('filename')
lines = file_object.readlines()
5nếu bạn dũng cảm).

25 hữu ích 1 bình luận chia sẻ 1 bình luận chia sẻ

Tôi muốn kiểm tra một số mã (python 3) sử dụng trực tiếp các hàm

file_object = open('filename')
lines = file_object.readlines()
6và
file_object = open('filename')
lines = file_object.readlines()
7. Theo tôi hiểu, cách dễ nhất để làm điều này là chèn phụ thuộc: sửa đổi mã để nó nhận các luồng đầu vào và đầu ra làm đối số, sử dụng
file_object = open('filename')
lines = file_object.readlines()
2và
file_object = open('filename')
lines = file_object.readlines()
9theo mặc định và chuyển vào các đối tượng giả trong quá trình thử nghiệm. Rõ ràng là phải làm gì với
file_object = open('filename')
lines = file_object.readlines()
6các cuộc gọi:

print(text)
#replaced with...
print(text, file=output_stream)

Tuy nhiên,

file_object = open('filename')
lines = file_object.readlines()
7không có đối số cho các luồng đầu vào và đầu ra. Đoạn mã sau có tái tạo chính xác hành vi của nó không?

text = input(prompt)
#replaced with...
print(prompt, file=output_stream, end='')
text = input_stream.readline()[:-1]

Tôi đã xem xét việc triển khai

file_object = open('filename')
lines = file_object.readlines()
7, và nó thực hiện khá nhiều phép thuật, gọi
for something in sys.stdin:
    some stuff here
3và kiểm tra
for something in sys.stdin:
    some stuff here
4và
for something in sys.stdin:
    some stuff here
5hơn là gọi bất kỳ
for something in sys.stdin:
    some stuff here
6phương pháp nào - tôi không biết bắt đầu từ đâu với việc chế giễu chúng.

  • python
  • dependency-injection
  • python-3.x
  • mocking
  • stdin

3 hữu ích 4 bình luận 4.0k xem chia sẻ 4 bình luận 4.0k xem chia sẻ

answer

6

Hướng dẫn sys.stdin python - trăn sys.stdin

for something in sys.stdin:
    some stuff here
7chỉ phép thuật mà bạn đã đề cập khi
for something in sys.stdin:
    some stuff here
8và
for something in sys.stdin:
    some stuff here
9không bị thay đổi, bởi vì chỉ khi đó nó mới có thể sử dụng những thứ như thư viện dòng đọc. Nếu bạn thay thế chúng bằng một cái gì đó khác (tệp thực hoặc không), nó sẽ đi đến mã sau:

/* Fallback if we're not interactive */
if (promptarg != NULL) {
    if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0)
         return NULL;
}
tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
if (tmp == NULL)
    PyErr_Clear();
else
    Py_DECREF(tmp);
return PyFile_GetLine(fin, -1);

Nơi

lines = sys.stdin.readlines()
0 gọi
lines = sys.stdin.readlines()
1 phương thức. Như vậy việc chế nhạo
lines = sys.stdin.readlines()
2sẽ có tác dụng.

Bạn nên thực hiện việc này với

lines = sys.stdin.readlines()
3bộ xử lý ngữ cảnh hoặc
lines = sys.stdin.readlines()
4mô-đun để kết quả đầu ra được khôi phục ngay cả khi mã bạn đang kiểm tra không thành công với các ngoại lệ:

from unittest.mock import patch
from io import StringIO

with patch("sys.stdin", StringIO("FOO")), patch("sys.stdout", new_callable=StringIO) as mocked_out:
    x = input()
    print("Read:", x)

assert mocked_out.getvalue() == "Read: FOO\n"

6 hữu ích 0 bình luận chia sẻ 0 bình luận chia sẻ

answer

5

for something in sys.stdin:
    some stuff here
7chỉ phép thuật mà bạn đã đề cập khi
for something in sys.stdin:
    some stuff here
8và
for something in sys.stdin:
    some stuff here
9không bị thay đổi, bởi vì chỉ khi đó nó mới có thể sử dụng những thứ như thư viện dòng đọc. Nếu bạn thay thế chúng bằng một cái gì đó khác (tệp thực hoặc không), nó sẽ đi đến mã sau:

original_stdin = sys.stdin
sys.stdin = open('inputfile.txt', 'r')

original_stdout = sys.stdout
sys.stdout = open('outputfile.txt', 'w')

response = input('say hi: ')
print(response)

sys.stdin = original_stdin
sys.stdout = original_stdout

Nơi

lines = sys.stdin.readlines()
0 gọi
lines = sys.stdin.readlines()
1 phương thức. Như vậy việc chế nhạo
lines = sys.stdin.readlines()
2sẽ có tác dụng.

file_object = open('filename')
lines = file_object.readlines()
0

Bạn nên thực hiện việc này với

lines = sys.stdin.readlines()
3bộ xử lý ngữ cảnh hoặc
lines = sys.stdin.readlines()
4mô-đun để kết quả đầu ra được khôi phục ngay cả khi mã bạn đang kiểm tra không thành công với các ngoại lệ:

6 hữu ích 0 bình luận chia sẻ

file_object = open('filename')
lines = file_object.readlines()
1

Nếu bạn gán một đối tượng giống tệp cho hàm

file_object = open('filename')
lines = file_object.readlines()
2của Python,
file_object = open('filename')
lines = file_object.readlines()
7hàm của Python sẽ sử dụng nó thay vì đầu vào chuẩn. Nhưng hãy nhớ gán
file_object = open('filename')
lines = file_object.readlines()
2lại cho đầu vào tiêu chuẩn sau khi bạn hoàn tất. Thủ thuật tương tự áp dụng cho
file_object = open('filename')
lines = file_object.readlines()
9. Bạn có thể làm điều gì đó như sau: 3 bình luận chia sẻ

Hai dòng này

sẽ sử dụng các tệp được chỉ định (
lines = sys.stdin.readlines()
9và
myprog.py < input_file.txt 
0) thay vì đầu vào tiêu chuẩn và đầu ra tiêu chuẩn.