python 会接受 -(破折号)作为 `open()` 的文件名以写入标准输出吗?
Will python accept - (dash) as a filename to `open()` to write to stdout?
我正在使用接受输出文件作为参数的 Python 脚本。它使用 open(outfile, "w")
打开并写入该文件。
Linux 中的一个常见约定是使用 -
(破折号)写入标准输出。 It is a common convention but not standard nor part of a shell.
我可以将 -
作为输出文件名传递,以便 Pythons open
写入标准输出吗?
您应该进行测试以确定,但根据 Python 文档:
open(file, mode='r', buffering=-1, encoding=None, errors=None,
newline=None, closefd=True, opener=None)
file is a path-like object giving the pathname (absolute or relative
to the current working directory) of the file to be opened or an
integer file descriptor of the file to be wrapped. (If a file
descriptor is given, it is closed when the returned I/O object is
closed, unless closefd is set to False.)
A path-like object is an object representing a file system path. A
path-like object is either a str or bytes object representing a path,
or an object implementing the os.PathLike protocol. An object that
supports the os.PathLike protocol can be converted to a str or bytes
file system path by calling the os.fspath() function; os.fsdecode()
and os.fsencode() can be used to guarantee a str or bytes result
instead, respectively. Introduced by PEP 519.
所以是的,它应该有效。
更多信息请参考https://docs.python.org/3/library/functions.html#open and https://docs.python.org/3/glossary.html#term-path-like-object。
这取决于您如何检索命令行参数。
使用 sys.argv、argparse 或 OptionParser 模块,可以。
这意味着您可以检索“-”。
但在这种情况下是否打开标准输出取决于您。
在 linux mint 19 (python 3.6) 上测试,似乎没有问题。你应该避免在文件名中使用的字符是:
\ / : * ? " < > |
其中一些实际上适用于 linux 但您为什么要牺牲便携性?
不,标准库 open()
function 不会将文件名 '-'
翻译成 stdin
或 stdout
。它只是一个 普通文件名 ,因此 open("-", "w")
将写入当前工作目录中名为 -
.
的文件
您必须显式测试该值,因此 return sys.stdin
或 sys.stdout
(取决于您需要读取或写入的内容),而不是打开文件.
例如click
command-line interface library, which supports using -
as a filename on the command line, explicitly tests for a '-'
filename in their open_stream()
implementation:
if filename == '-':
if any(m in mode for m in ['w', 'a', 'x']):
if 'b' in mode:
return get_binary_stdout(), False
return get_text_stdout(encoding=encoding, errors=errors), False
if 'b' in mode:
return get_binary_stdin(), False
return get_text_stdin(encoding=encoding, errors=errors), False
open()
确实接受 file handles,因此您可以为标准输入传入 0
,或为标准输出传入 1
:
>>> inp = open(0)
>>> inp
<_io.TextIOWrapper name=0 mode='r' encoding='UTF-8'>
>>> inp.read(1) # read 1 character from stdin, I entered 'a'
a
'a'
>>> outp = open(1, 'w')
>>> outp
<_io.TextIOWrapper name=1 mode='w' encoding='UTF-8'>
>>> outp.write("foo!") # line buffered, no newline written so not visible yet
4
>>> outp.flush() # flush the buffer
foo!>>>
我正在使用接受输出文件作为参数的 Python 脚本。它使用 open(outfile, "w")
打开并写入该文件。
Linux 中的一个常见约定是使用 -
(破折号)写入标准输出。 It is a common convention but not standard nor part of a shell.
我可以将 -
作为输出文件名传递,以便 Pythons open
写入标准输出吗?
您应该进行测试以确定,但根据 Python 文档:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file is a path-like object giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped. (If a file descriptor is given, it is closed when the returned I/O object is closed, unless closefd is set to False.)
A path-like object is an object representing a file system path. A path-like object is either a str or bytes object representing a path, or an object implementing the os.PathLike protocol. An object that supports the os.PathLike protocol can be converted to a str or bytes file system path by calling the os.fspath() function; os.fsdecode() and os.fsencode() can be used to guarantee a str or bytes result instead, respectively. Introduced by PEP 519.
所以是的,它应该有效。
更多信息请参考https://docs.python.org/3/library/functions.html#open and https://docs.python.org/3/glossary.html#term-path-like-object。
这取决于您如何检索命令行参数。 使用 sys.argv、argparse 或 OptionParser 模块,可以。 这意味着您可以检索“-”。 但在这种情况下是否打开标准输出取决于您。
在 linux mint 19 (python 3.6) 上测试,似乎没有问题。你应该避免在文件名中使用的字符是:
\ / : * ? " < > |
其中一些实际上适用于 linux 但您为什么要牺牲便携性?
不,标准库 open()
function 不会将文件名 '-'
翻译成 stdin
或 stdout
。它只是一个 普通文件名 ,因此 open("-", "w")
将写入当前工作目录中名为 -
.
您必须显式测试该值,因此 return sys.stdin
或 sys.stdout
(取决于您需要读取或写入的内容),而不是打开文件.
例如click
command-line interface library, which supports using -
as a filename on the command line, explicitly tests for a '-'
filename in their open_stream()
implementation:
if filename == '-':
if any(m in mode for m in ['w', 'a', 'x']):
if 'b' in mode:
return get_binary_stdout(), False
return get_text_stdout(encoding=encoding, errors=errors), False
if 'b' in mode:
return get_binary_stdin(), False
return get_text_stdin(encoding=encoding, errors=errors), False
open()
确实接受 file handles,因此您可以为标准输入传入 0
,或为标准输出传入 1
:
>>> inp = open(0)
>>> inp
<_io.TextIOWrapper name=0 mode='r' encoding='UTF-8'>
>>> inp.read(1) # read 1 character from stdin, I entered 'a'
a
'a'
>>> outp = open(1, 'w')
>>> outp
<_io.TextIOWrapper name=1 mode='w' encoding='UTF-8'>
>>> outp.write("foo!") # line buffered, no newline written so not visible yet
4
>>> outp.flush() # flush the buffer
foo!>>>