我想从另一个Python脚本运行一个Python脚本。我想像使用命令行那样传递变量。例如,我将运行我的第一个脚本,该脚本将遍历值列表(0,1,2,3)并将其传递给到第二个脚本script2.py 0然后script2.py 1等。函数,balpha的答案将调用脚本,但不带参数。我将其更改为以下内容,以进行测试:当我在script2.py中打印出sys.argv时,它是对第一个脚本“ ['C:\ script1.py']的原始命令调用。

我真的不想更改原始脚本(例如,在我的示例中为script2.py),因为我不拥有它。 br />

评论

如果os.system对您来说不够强大,则有子进程模块。

问题是您是否知道脚本的名称(然后将其导入),还是在编程时不知道脚本的名称(然后使用subprocess.call)。在第二种情况下,这个问题也不会重复。因为问题不清楚,所以也不是一个好问题。

@Trilarion:错了。即使名称是在运行时生成的,也可以导入python模块。

@Trilarion:为什么要全部覆盖?名称在两个问题中都是固定的。无论如何,声明“如果您在编程时不知道脚本名称(请使用subprocess.call)”。不管是错的。如果您有新问题;问。

@ Oli4“绝对”是一个很强的词。关心详细吗?我看到subprocess.call()解决方案接受传递多个命令行参数。我看到在定义main()函数的情况下提到了导入(它对OP没有帮助,但对于许多其他存在类似问题的人来说,这是正确的方法)。我看到了适用于Python 2的execfile(),它使用了您在sys.argv中添加的任何内容(顺便说一句,没有明确提及最后一位)-初学者应该忽略此选项。甚至有一个带有多个参数的os.system()显式答案(此处接受了答案)。

#1 楼

尝试使用os.system

os.system("script2.py 1")


execfile有所不同,因为它被设计为在当前执行上下文中运行一系列Python语句。这就是为什么sys.argv不会为您改变。

评论


我认为通常最好使用subprocess.Popen而不是os.system:docs.python.org/library/subprocess.html#replacing-os-system。

–卡特里尔
2010-09-23 20:15

是的,这就是os.system的帮助所说的。但是,对于简单用途,os.system是完成工作的最简单方法。当然,这取决于您的需求。

– Greg Hewgill
2010-09-23 20:39

您必须添加python才能运行脚本:os.system(“ python script2.py 1”)

– Andromida
2014年1月2日,13:10

@macdonjo:否,os.system()调用会等到您调用的操作完成后再继续。您可以使用subprocess.Popen()自己管理新流程,也可以使用多处理模块或其他各种解决方案。

– Greg Hewgill
2014年1月27日,下午2:58

我遇到问题sh:1:* .py:找不到。添加python,然后它可以工作,即os.system(“ python script2.py 1”)。

–SparkAndShine
16年4月21日在21:48

#2 楼

本质上,这是错误的做法。如果要从另一个Python脚本运行Python脚本,则应该通过Python而不是通过OS进行通信:

直接在script1内部调用函数:

import script1

sys.argv。有一种使用上下文管理器执行此操作的整洁方法,可确保您不进行任何永久更改。

for i in range(whatever):
    script1.some_function(i)


我认为这比传递所有数据更可取到操作系统并返回;那真是愚蠢。

评论


这可能是“错误的”事情,但是如果您要引用的脚本没有主要功能或函数...该怎么办呢?导入将在导入时执行脚本,这可能不是您想要的(并且您不希望重构它,因为人们也按原样使用该脚本。操作系统/子进程可以处理这种情况

– Dan S
2012年8月21日15:33

是的,但这是IMO的另一个问题!

–卡特里尔
2012年8月21日在16:08

多线程脚本不会失败吗?

– MarioVilas
13年3月13日在11:01

从更高的角度来看,将此策略称为“错误”是“错误的”。当系统扩大规模时,详细了解组件的内部工作将成为一个越来越大的问题-用Python编写的程序可能会用另一种语言重新设计,并且使用操作系统的通用过程通信功能可以提供很多服务作为策略。

–稳定狗
18年7月28日在21:43

...以及依赖关系如何?如果每个脚本都有自己的依赖性,那么为什么第一个脚本应该知道第二个脚本的所有依赖性?从架构的角度来看,错误是在python中直接调用导入(IMHO)

– 4lberto
19年2月9日在21:25

#3 楼

理想情况下,您要运行的Python脚本将在末尾使用以下代码进行设置:

def main(arg1, arg2, etc):
    # do whatever the script does


if __name__ == "__main__":
    main(sys.argv[1], sys.argv[2], sys.argv[3])


换句话说,如果从命令中调用了模块行,它解析命令行选项,然后调用另一个函数main()来完成实际工作。 (实际的参数会有所不同,并且解析可能会涉及到更多。)

但是,如果您想从另一个Python脚本中调用这样的脚本,则可以简单地import并直接调用modulename.main()比通过操作系统更有效。 。

评论


回复:“没有葡萄干。”这不是错误。但是,很有趣的是,一个不熟悉Futurama的人花了两年零三个月的随机堆栈溢出问题来“纠正”它需要多长时间。 :-)

– Kindall
2012年12月29日18:30



我嘲笑“没有葡萄干”仅仅是因为这是一个荒谬的错字,然后看到您的评论并在YouTube上找到了一个剪辑。甚至更有趣。

– Armani
13年5月20日在15:51

我有一个没有main的脚本,但是可以这样介绍:1.分离函数defs和独立语句2.在“ if name ...”部分下进行参数解析3.在def main下缩进其余语句(...),并让该逻辑对方法参数进行操作。然后,我能够从另一个脚本调用main方法(例如:单元测试)

– Stan Kurdziel
13年5月28日在18:00

是的,Python确实使这种重构非常容易。我自己做过不止一次类似的事情!

– Kindall
13年5月28日在18:06

如果主程序具有可选参数,则这种方法对我不起作用。在这里,我得到“列表索引超出范围”。最好有一个Main(sys.argv)并处理Main中的参数列表

– 576i
2014年11月11日上午8:48

#4 楼

我认为好的做法可能是这样的;

import subprocess
cmd = 'python script.py'

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
out, err = p.communicate() 
result = out.split('\n')
for lin in result:
    if not lin.startswith('#'):
        print(lin)

根据文档
子进程模块允许您生成新进程,连接到其输入/输出/错误管道并获取其返回代码。该模块旨在替换一些较旧的模块和功能:

os.system
os.spawn*
os.popen*
popen2.*
commands.*


使用communication()而不是.stdin.write,.stdout.read或.stderr.read来避免由于任何其他OS管道缓冲区填满并阻塞子进程而导致死锁。
此处阅读

#5 楼

子流程模块:http://docs.python.org/dev/library/subprocess.html#using-the-subprocess-module

import subprocess
subprocess.Popen("script2.py 1", shell=True)


这样,您可以还重定向stdin,stdout和stderr。

评论


除非必要,否则不要使用shell = True。

–彼得·多布罗格斯特(Piotr Dobrogost)
13年3月3日,10:39

@PiotrDobrogost您可以详细说明吗?编辑:对于任何好奇的人,这是为什么的解释:stackoverflow.com/questions/3172470/…

– emilaz
20-2-13在17:10



#6 楼

import subprocess
subprocess.call(" python script2.py 1", shell=True)


评论


您可能希望扩展答案,以解释为什么这是比此处提供的其他一些答案更好的选择。

–邓肯·琼斯(Duncan Jones)
13年11月12日在12:29

如何传递参数而不是字符串,例如列表?除了单独传递每个元素之外,还有其他选择吗?

– Michu93
16年7月21日在9:20

除非必要,否则不要使用shell = True。

–阿米(Ami Mahloof)
17-10-9在19:29