在没有Popen或os.system的情况下从python运行python

时间:2013-02-08 18:27:43

标签: python

我有一个包装器python脚本,它通过os.system重复调用另一个python脚本。这样做效果很好,但是调用子shell并一次又一次地导入模块会有很大的性能损失。我怎么能把它变成更优雅和高效的东西呢?

counter = 0
for thing in list_of_stuff:
    os.system("python inner_script.py %s result_%s" % (thing, counter)
    counter += 1

我更愿意在包装器中执行此操作,但如果这是唯一或最好的方法,则可以修改 inner-script.py

如果相关,则环境是Windows上的Python 2.7。

编辑:我不只是导入inner_script,因为它不了解命令行参数:

import inner_script    
counter = 0
for thing in ['TR2','TR5']:
    inner_script('%s result_%s' % (thing, counter))
counter += 1

结果:

C:\> python xx-wrapper.py

inner_script [input features] [output workspace]

这是inner_script.py返回的用法消息:

if len(sys.argv) < 3:
    print usage
    exit()

in_features = sys.argv[1]
out_folder  = sys.argv[2]

main(in_features, out_folder)

3 个答案:

答案 0 :(得分:3)

目标是能够写下:

from inner_module import some_function

for counter, thing in enumerate(list_of_stuff):
    some_function(thing, counter)

要实现它,请将处理代码从内部脚本移动到单独的函数。您可以将其放入新模块或重命名脚本并将该功能保留在那里。例如,inner-script.py

import sys
# tons of other imports..

# parse args
thing, counter = sys.argv[1:]

# do something..
print thing, counter

可以转换为inner_module.py

import sys
# tons of other imports..

def some_function(thing, counter):
    print thing, counter

def main():
    # parse args
    thing, counter = sys.argv[1:]

    # do something..
    some_function(thing, counter)

if __name__=="__main__":
    main()

答案 1 :(得分:2)

inner-script.py中创建一个围绕脚本执行任务的类。

for thing in list_of_stuff:
    x = __import__('inner-script')
    x.className(thing, counter)

这应该足够有效。


或者,如果你不能/不会修改inner-script.py,这里有一种方法可以在python中调用它,并将变量作为local()或global()变量传递给脚本可以读取...好像你在你的例子中执行时传递了params:

x = __import__('inner-script', globals(), (thing, counter), [], -1)

然后你想成为什么东西,more info can be found here

答案 2 :(得分:0)

感谢Torxed's answer及附带的评论,我有一些看似适用于“不要修改inner_script”的方案。虽然最初的目标已经完成,但在构建过程中,我已经清楚地知道,最好的办法是在J.F. Sebastian's template后重新inner-scriptinner_script模块中。有太多的东西可能会或可能不会正常使用,但是, 是一个答案,所以我把它留给其他可能需要它的人:

counter = 0
for thing in ['1st','2nd', '3rd']:
    output = '%s_%s' % (thing, counter)
    sys.argv.insert(1, thing)
    sys.argv.insert(2, output)

    if counter == 0:
        x = __import__('inner_script', sys.argv)
    else:
        reload(x)

    del sys.argv[2] # in reverse order so as not to change index #'s before done
    del sys.argv[1] 
    counter += 1

结果:

Processing 1st into 1st_0
Processing 2nd into 2nd_1
Processing 3rd into 3rd_2