如何将一个脚本的输出作为输入传递给另一个脚本?例如,如果a.py输出format.xml,那么a.py如何调用b.py并将参数format.xml传递给它?我认为它应该像在命令行上完成管道一样工作。
我被一群具有领域特定知识的科学家聘用,但有时候计算机编程要求没有意义。有一长串“模块”,我的老板非常坚持认为1个模块是1个python脚本,而一个模块的输出是下一个模块的输入。我对Python很陌生,但如果这个设计模式给任何人敲响了,请告诉我。
更糟糕的是,该项目将被转换为可执行格式(使用py2exe),并且仍然必须有与.py文件相同数量的可执行文件。
答案 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.