我有一个名为test1.py的脚本,它不在模块中。它只有在脚本本身运行时应该执行的代码。没有函数、类、方法等。我有另一个作为服务运行的脚本。我想从作为服务运行的脚本调用test1.py。
例如:文件Test1.Py
print"I am a test"
print"see! I do nothing productive."
文件服务
# Lots of stuff here
test1.py # do whatever is in test1.py
我知道一种方法,就是打开文件,读取内容,然后基本上对其进行评估。我想有更好的办法。或者至少我希望如此。
更好的方法是编写方法和类并使用它们
相关:python 3:使用子进程在python脚本中调用输入为的python脚本
通常的方法如下。
Test1.Py
def some_func():
print 'in test 1, unproductive'
if __name__ == '__main__':
# test1.py executed as script
# do something
some_func()
Service
import test1
def service_func():
print 'service func'
if __name__ == '__main__':
# service.py executed as script
# do something
service_func()
test1.some_func()
如果test1.py位于某个遥远的目录中呢?
@evgenisegeev请参阅stackoverflow.com/questions/67631/…
你为什么把它命名为"some func()"而不是"main()"?
@卢卡斯马勒:大概是因为它通常不是main()函数——在这种情况下,它不会很有描述性(或准确性)。
因此,如果您有两个可以独立地从文件文件夹运行的工作脚本,但希望能够从单独的"菜单"程序调用它们,那么这是使之成为可能的方法吗?
但这并不能真正回答问题,是吗?您没有执行整个脚本,而是从导入的脚本中执行一些函数。
@你错了。service.py中的import test1确实执行了整个脚本(仅定义some_func(),因为在这种情况下,__name__ == '__main__'将是False)。这听起来像是所有的运营商都想做的。这个答案超出了这个范围,但肯定会回答这个问题,然后是一些。
比如说,如果test1.py不包含函数some_func()的定义(而只是一些代码行,例如print("hello")),那么您的代码就不会工作。在这个特定的示例中,它确实起作用,因为您实际上正在导入一个外部函数,您随后将调用它。
这在Python2中可以使用
execfile("test2.py")
如果名称空间在您的案例中很重要,请参阅有关名称空间处理的文档。
但是,您应该考虑使用不同的方法;您的想法(从我所看到的)看起来不太干净。
我在python 32中直接需要的是exec(open('test2.py').read())
此方法执行调用命名空间中的脚本。:)
这显然不是"最好"或"最Python"的方法,但这正是我想要的:)
要将命令行参数传递给脚本,可以编辑sys.argv列表。
对python 3的更全面的处理:stackoverflow.com/questions/436198/…
这不接受参数(要传递到py文件)!
另一种方式:文件TEST1.PY:
print"test1.py"
文件服务.py:
import subprocess
subprocess.call("test1.py", shell=True)
这种方法的优点是,不必编辑现有的python脚本来将其所有代码放入子例程中。
文档:python 2、python 3
我不得不用subprocess.call("./test1.py", shell=True)使它起作用。
除非必要,否则不要使用shell=True。
@piotrodobrogost-您能具体说明哪些情况会使它成为必要的吗?
@例如,当您有相当复杂的bash命令并且不想将其转换为python代码时。
它不能在当前目录不在路径中的典型UNIX上工作。test1.py应该是可执行的,并且有shebang行(#!/usr/bin/env python),您应该指定完整的路径,或者您需要自己提供可执行文件:call([sys.executable, os.path.join(get_script_dir(), 'test1.py')]),这里定义get_script_dir()。
我不得不使用subprocess.call("python test1.py",shell=true)使其作为默认程序工作,以便在我的工作站上打开"py"文件是记事本而不是python.exe。
这很好,但它与Python 2.4+配合使用。必须使用python 2.1的PPL怎么样
只要运行的shell命令不是由用户输入形成的,shell=True就可以了。否则会有注入壳牌的风险。
它应该用subprocess.call("python test1.py", shell=True)来代替。
或subprocess.call(['python', 'test1.py'])。
如果希望test1.py保持可执行性,并具有与在service.py中调用它时相同的功能,则执行如下操作:
Test1.Py
def main():
print"I am a test"
print"see! I do nothing productive."
if __name__ =="__main__":
main()
Service
import test1
# lots of stuff here
test1.main() # do whatever is in test1.py
如果你有运行时参数怎么办?
你不应该这样做。相反,做:
Test1.Py:
def print_test():
print"I am a test"
print"see! I do nothing productive."
Service
#near the top
from test1 import print_test
#lots of stuff here
print_test()
导入test1时,它如何知道文件在哪里?它必须在同一个目录中吗?如果不是呢?
第一次使用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()'。
import sys
if sys.modules.has_key['test1']:
reload(sys.modules['test1'])
else:
__import__('test1')
在python 3中,reload已不复存在。
导入模块并不等同于运行它,例如,考虑if __name__ =="__main__":保护。可能还有其他更微妙的差异。不要将任意代码留在全局级别。将其放入函数中,并在导入后调用它,如接受的答案中建议的那样。
import os
os.system("python myOtherScript.py arg1 arg2 arg3")
使用操作系统,您可以直接呼叫终端。如果您想更加具体,可以将输入字符串与局部变量连接起来,即。
command = 'python myOtherScript.py ' + sys.argv[1] + ' ' + sys.argv[2]
os.system(command)
应避免调用os.system,您可以对Popen, Call,中的任何类执行相同的操作。
从python文档中可以看出:子进程模块为生成新进程和检索其结果提供了更强大的工具;使用该模块比使用该函数更好。
这是subprocess库的一个例子:
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作为子进程执行。