在 python 中使用多个输出流?
Use multiple output stream in python?
我要做的是在 python 函数中创建多个输出流,并将它们称为 1
、2
、3
... ..:
在 test.py
:
def main():
...
print >>fd1, 'words1'
print >>fd2, 'words2'
print >>fd3, 'words3'
...
使用时重定向:
python test.py 1>1.txt 2>2.txt 3>3.txt
这些文件的内容:
1.txt -> words1
2.txt -> words2
3.txt -> words3
问题是,如何创建那些fd1
、fd2
、fd3
?
已添加:
我用过这个:
outfiles = {}
for _ in range(3):
fd = os.dup(1)
outfiles[fd] = os.fdopen(fd, 'w')
def main():
for no in outfiles:
print >>outfiles[no], "foo"
print >>outfiles[no], outfiles[no].fileno()
但结果取决于我如何执行这段代码:
eg1:
python test.py
foo
3
foo
4
foo
5
eg2:
python test.py 3>log.txt
foo
4
foo
5
foo
6
eg3:
python test.py 1>log.txt
Nothing printed
所以我猜,输出实际上是1
,如果文件描述符已经在执行中使用(例如:python test.py 3>log.txt
),那么os.dup(1)就赢了不再 return 它了。
在 Linux,您想要的文件句柄存在于 /proc/self/fd/
。例如:
with open('/proc/self/fd/1', 'w') as fd1, open('/proc/self/fd/2', 'w') as fd2, open('/proc/self/fd/3', 'w') as fd3:
print >>fd1, 'words1'
print >>fd2, 'words2'
print >>fd3, 'words3'
在其他一些 Unice 上,您可能会在 /dev/fd
.
下找到类似的文件句柄
现在,您可以 运行 您的命令并验证输出文件是否符合要求:
$ python test.py 1>1.txt 2>2.txt 3>3.txt
$ cat 1.txt
words1
$ cat 2.txt
words2
$ cat 3.txt
words3
打开文件描述符的数量限制
OS 对一个进程可以打开的文件描述符的最大数量进行了限制。有关此内容的讨论,请参阅 "Limits on the number of file descriptors"。
使用 bash 的编号文件描述符时,限制要严格得多。在bash下,只为用户保留最多9个的文件描述符。使用更大的数字可能会与 bash 的内部使用发生冲突。来自 man bash
:
Redirections using file descriptors greater than 9 should be used with
care, as they may conflict with file descriptors the shell uses
internally.
如果根据评论,您想要分配数百个文件描述符,则不要使用 shell 重定向或 /proc/self/fd
中的编号描述符。相反,使用 python 的打开命令,例如open('255.txt', 'w')
直接在您想要的每个输出文件上。
为此您需要模块 os
。首先,复制标准输出(根据需要多次)并为其构建一个高级文件对象。通常,stdout 的第一个副本是文件描述符 #3.
outfiles = {} # a future dictionary of output file objects
for _ in range(N): # How many streams do you want?
new_stdout = os.dup(1)
outfiles[new_stdout] = os.fdopen(new_stdout, mode='w')
现在,您可以使用新的文件对象进行打印:
print("foo", file=outfiles[3]) # Sames as print >>outfiles[3], "foo" in 2.7
> python myfile.py 3>3.txt
# There is foo in 3.txt now
重新定义文件描述符 0、1 和 2 是一个非常糟糕的主意。请不要这样做。
我要做的是在 python 函数中创建多个输出流,并将它们称为 1
、2
、3
... ..:
在 test.py
:
def main():
...
print >>fd1, 'words1'
print >>fd2, 'words2'
print >>fd3, 'words3'
...
使用时重定向:
python test.py 1>1.txt 2>2.txt 3>3.txt
这些文件的内容:
1.txt -> words1
2.txt -> words2
3.txt -> words3
问题是,如何创建那些fd1
、fd2
、fd3
?
已添加:
我用过这个:
outfiles = {}
for _ in range(3):
fd = os.dup(1)
outfiles[fd] = os.fdopen(fd, 'w')
def main():
for no in outfiles:
print >>outfiles[no], "foo"
print >>outfiles[no], outfiles[no].fileno()
但结果取决于我如何执行这段代码:
eg1:
python test.py
foo
3
foo
4
foo
5
eg2:
python test.py 3>log.txt
foo
4
foo
5
foo
6
eg3:
python test.py 1>log.txt
Nothing printed
所以我猜,输出实际上是1
,如果文件描述符已经在执行中使用(例如:python test.py 3>log.txt
),那么os.dup(1)就赢了不再 return 它了。
在 Linux,您想要的文件句柄存在于 /proc/self/fd/
。例如:
with open('/proc/self/fd/1', 'w') as fd1, open('/proc/self/fd/2', 'w') as fd2, open('/proc/self/fd/3', 'w') as fd3:
print >>fd1, 'words1'
print >>fd2, 'words2'
print >>fd3, 'words3'
在其他一些 Unice 上,您可能会在 /dev/fd
.
现在,您可以 运行 您的命令并验证输出文件是否符合要求:
$ python test.py 1>1.txt 2>2.txt 3>3.txt
$ cat 1.txt
words1
$ cat 2.txt
words2
$ cat 3.txt
words3
打开文件描述符的数量限制
OS 对一个进程可以打开的文件描述符的最大数量进行了限制。有关此内容的讨论,请参阅 "Limits on the number of file descriptors"。
使用 bash 的编号文件描述符时,限制要严格得多。在bash下,只为用户保留最多9个的文件描述符。使用更大的数字可能会与 bash 的内部使用发生冲突。来自 man bash
:
Redirections using file descriptors greater than 9 should be used with care, as they may conflict with file descriptors the shell uses internally.
如果根据评论,您想要分配数百个文件描述符,则不要使用 shell 重定向或 /proc/self/fd
中的编号描述符。相反,使用 python 的打开命令,例如open('255.txt', 'w')
直接在您想要的每个输出文件上。
为此您需要模块 os
。首先,复制标准输出(根据需要多次)并为其构建一个高级文件对象。通常,stdout 的第一个副本是文件描述符 #3.
outfiles = {} # a future dictionary of output file objects
for _ in range(N): # How many streams do you want?
new_stdout = os.dup(1)
outfiles[new_stdout] = os.fdopen(new_stdout, mode='w')
现在,您可以使用新的文件对象进行打印:
print("foo", file=outfiles[3]) # Sames as print >>outfiles[3], "foo" in 2.7
> python myfile.py 3>3.txt
# There is foo in 3.txt now
重新定义文件描述符 0、1 和 2 是一个非常糟糕的主意。请不要这样做。