关于python:从另一个脚本调用脚本的最佳方法是什么?

What is the best way to call a script from another script?

我有一个名为test1.py的脚本,它不在模块中。它只有在脚本本身运行时应该执行的代码。没有函数、类、方法等。我有另一个作为服务运行的脚本。我想从作为服务运行的脚本调用test1.py。

例如:

文件Test1.Py

1
2
print"I am a test"
print"see! I do nothing productive."

文件服务

1
2
# Lots of stuff here
test1.py # do whatever is in test1.py

我知道一种方法,就是打开文件,读取内容,然后基本上对其进行评估。我想有更好的办法。或者至少我希望如此。


通常的方法如下。

Test1.Py

1
2
3
4
5
6
7
def some_func():
    print 'in test 1, unproductive'

if __name__ == '__main__':
    # test1.py executed as script
    # do something
    some_func()

Service

1
2
3
4
5
6
7
8
9
10
import test1

def service_func():
    print 'service func'

if __name__ == '__main__':
    # service.py executed as script
    # do something
    service_func()
    test1.some_func()


这在Python2中可以使用

1
execfile("test2.py")

如果名称空间在您的案例中很重要,请参阅有关名称空间处理的文档。

但是,您应该考虑使用不同的方法;您的想法(从我所看到的)看起来不太干净。


另一种方式:

文件TEST1.PY:

1
print"test1.py"

文件服务.py:

1
2
3
import subprocess

subprocess.call("test1.py", shell=True)

这种方法的优点是,不必编辑现有的python脚本来将其所有代码放入子例程中。

文档:python 2、python 3


如果希望test1.py保持可执行性,并具有与在service.py中调用它时相同的功能,则执行如下操作:

Test1.Py

1
2
3
4
5
6
def main():
    print"I am a test"
    print"see! I do nothing productive."

if __name__ =="__main__":
    main()

Service

1
2
3
import test1
# lots of stuff here
test1.main() # do whatever is in test1.py


你不应该这样做。相反,做:

Test1.Py:

1
2
3
 def print_test():
      print"I am a test"
      print"see! I do nothing productive."

Service

1
2
3
4
#near the top
from test1 import print_test
#lots of stuff here
print_test()


第一次使用import test1—它将执行脚本。对于以后的调用,将脚本视为导入的模块,并调用reload(test1)方法。

When reload(module) is executed:

  • Python modules’ code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the module’s dictionary. The init function of extension modules is not called

可以使用对sys.modules的简单检查来调用适当的操作。要继续将脚本名称作为字符串引用('test1'),请使用内置的'import()'。

1
2
3
4
5
import sys
if sys.modules.has_key['test1']:
    reload(sys.modules['test1'])
else:
    __import__('test1')


1
2
3
import os

os.system("python myOtherScript.py arg1 arg2 arg3")

使用操作系统,您可以直接呼叫终端。如果您想更加具体,可以将输入字符串与局部变量连接起来,即。

1
2
command = 'python myOtherScript.py ' + sys.argv[1] + ' ' + sys.argv[2]
os.system(command)


这是subprocess库的一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import subprocess

python_version = '3'
path_to_run = './'
py_name = '__main__.py'

# args = [f"python{python_version}", f"{path_to_run}{py_name}"]  # Avaible in python3
args = ["python{}".format(python_version),"{}{}".format(path_to_run, py_name)]

res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()

if not error_:
    print(output)
else:
    print(error_)

为什么不直接导入测试1?每个python脚本都是一个模块。更好的方法是拥有一个函数,例如在test1.py中运行main/run,导入test1并运行test1.main()。或者可以将test1.py作为子进程执行。