输出一个文件输入到下一个

时间:2015-06-15 06:48:02

标签: python python-3.x requirements

如何将一个脚本的输出作为输入传递给另一个脚本?例如,如果a.py输出format.xml,那么a.py如何调用b.py并将参数format.xml传递给它?我认为它应该像在命令行上完成管道一样工作。

我被一群具有领域特定知识的科学家聘用,但有时候计算机编程要求没有意义。有一长串“模块”,我的老板非常坚持认为1个模块是1个python脚本,而一个模块的输出是下一个模块的输入。我对Python很陌生,但如果这个设计模式给任何人敲响了,请告诉我。

更糟糕的是,该项目将被转换为可执行格式(使用py2exe),并且仍然必须有与.py文件相同数量的可执行文件。

2 个答案:

答案 0 :(得分:1)

在某些情况下,这种模式很有意义,但对我而言,当你希望能够将每个模块作为一个自持的可执行模块运行时。

即。如果您想使用FORTRAN或类似语言中的脚本,最简单的方法是将python模块构建为可执行文件,然后从FORTRAN调用它。

这并不意味着一个模块是pr定义1 python文件,只是它只有一个入口点,并且实际上是可执行的。

一个模块的pr脚本可能是为了更容易找到代码。或者将其邮寄给某人进行代码检查或同行评审(通常在科学界进行)

因此,要求可能是技术和社会要求的混合。

无论如何回到问题。

我会使用子进程模块来调用下一个模块。 (close_fds设置为true)

  

如果close_fds为true,则除0,1和2之外的所有文件描述符都将为   在子进程执行之前关闭。 (仅限Unix)。或者,在   Windows,如果close_fds为true,那么将不会继承任何句柄   儿童过程。请注意,在Windows上,您无法将close_fds设置为true   并通过设置stdin,stdout或来重定向标准句柄   标准错误,

答案 1 :(得分:0)

To emulate a | b shell pipeline in Python:

#!/usr/bin/env python
from subprocess import check_call

check_call('a | b', shell=True)

a program writes to its stdout stream and knows nothing about b program. b program reads from its stdin and knows nothing about a program.

A more flexible approach is to define functions, classes in a.py, b.py modules that work with objects and to implement the command-line interface that produces/consumes xml in terms of these functions in if __name__ == "__main__" block e.g., a.py:

#!/usr/bin/env python
import sys
import xml.etree.ElementTree as etree

def items():
    yield {'name': 'a'}
    yield {'name': 'b'}

def main():
   parent = etree.Element("items")
   for item in items():
       etree.SubElement(parent, 'item', attrib=item)
   etree.ElementTree(parent).write(sys.stdout) # set encoding="unicode" on Python 3

if __name__=="__main__":
    main()

It would allow to avoid unnecessary serialization to xml/deserialization from xml when the scripts are not called from the command line:

#!/usr/bin/env python
import a, b

for item in a.items():
    b.consume(item)

Note: item can be an arbitrary Python object such as dict or an instance of a custom class.