[英]Read from File, or STDIN
我編寫了一個命令行實用程序,它使用 getopt 來解析命令行上給出的 arguments。 我還想讓文件名成為可選參數,例如在 grep、cut 等其他實用程序中。所以,我希望它具有以下用法
tool -d character -f integer [filename]
我該如何實施以下內容?
fileinput模塊可以做你想做的 - 假設非選項參數在args
那么:
import fileinput
for line in fileinput.input(args):
print line
如果args
為空,則fileinput.input()
將從標准輸入讀取; 否則它會依次從每個文件中讀取,類似於 Perl 的while(<>)
。
用最簡單的話來說:
import sys
# parse command line
if file_name_given:
inf = open(file_name_given)
else:
inf = sys.stdin
此時,您將使用inf
從文件中讀取。 根據是否給定文件名,這將從給定的文件或標准輸入讀取。
當您需要關閉文件時,您可以這樣做:
if inf is not sys.stdin:
inf.close()
然而,在大多數情況下,如果你完成了關閉sys.stdin
是無害的。
我喜歡使用上下文管理器的一般習慣用法,但是當您退出with
語句時,(太)瑣碎的解決方案最終會關閉sys.stdin
,我想避免這種情況。
借用這個答案,這是一個解決方法:
import sys
import contextlib
@contextlib.contextmanager
def _smart_open(filename, mode='Ur'):
if filename == '-':
if mode is None or mode == '' or 'r' in mode:
fh = sys.stdin
else:
fh = sys.stdout
else:
fh = open(filename, mode)
try:
yield fh
finally:
if filename != '-':
fh.close()
if __name__ == '__main__':
args = sys.argv[1:]
if args == []:
args = ['-']
for filearg in args:
with _smart_open(filearg) as handle:
do_stuff(handle)
我更喜歡使用“-”作為您應該從標准輸入讀取的指示符,它更明確:
import sys
with open(sys.argv[1], 'r') if sys.argv[1] is not "-" else sys.stdin as f:
pass # do something here
要使用 python 的with
語句,可以使用以下代碼:
import sys
with open(sys.argv[1], 'r') if len(sys.argv) > 1 else sys.stdin as f:
# read data using f
# ......
不是直接的答案,而是相關的。
通常,當您編寫 python 腳本時,您可以使用argparse
包。 如果是這種情況,您可以使用:
parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
'?'。 如果可能,將從命令行使用一個參數,並作為單個項目生成。 如果不存在命令行參數,則將生成默認值。
在這里我們將默認設置為sys.stdin
;
所以如果有一個文件,它將讀取它,如果沒有,它將從標准輸入中獲取輸入“注意:我們在上面的例子中使用了位置參數”
更多訪問: https : //docs.python.org/2/library/argparse.html#nargs
切換到argparse
(它也是標准庫的一部分)並使用默認值為 stdin 的argparse.FileType
:
import argparse, sys
p = argparse.ArgumentParser()
p.add_argument('input', nargs='?',
type=argparse.FileType(), default=sys.stdin)
args = p.parse_args()
print(args.input.readlines())
但是,這不會讓您為 stdin 指定編碼和其他參數; 如果你想這樣做,你需要使參數成為非可選的,並讓FileType
在-
作為參數給出時使用 stdin 做它的事情:
p.add_argument('input', type=FileType(encoding='UTF-8'))
請注意,后一種情況將不支持二進制模式 ( 'b'
) I/O。 如果您只需要它,您可以使用上面的默認參數技術,但提取二進制 I/O 對象,例如,對於 stdout, default=sys.stdout.buffer
。 但是,如果用戶指定-
無論如何,這仍然會中斷。 (使用-
stdin/stdout 始終包裝在TextIOWrapper
。)
如果您希望它與-
,或者在打開文件時需要提供任何其他參數,則可以在包裝錯誤時修復該參數:
p.add_argument('output', type=argparse.FileType('wb'))
args = p.parse_args()
if hasattr(args.output, 'buffer'):
# If the argument was '-', FileType('wb') ignores the 'b' when
# wrapping stdout. Fix that by grabbing the underlying binary writer.
args.output = args.output.buffer
(提示medhat提及add_argument()
的type
參數。)
就像是:
if input_from_file:
f = open(file_name, "rt")
else:
f = sys.stdin
inL = f.readline()
while inL:
print inL.rstrip()
inL = f.readline()
KISS 解決方案是:
if file == "-":
content = sys.stdin.read()
else:
with open(file) as f:
content = f.read()
print(content) # Or whatever you want to do with the content of the file.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.