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

这篇博客探讨了如何在Python中从一个脚本调用另一个脚本的不同方法,包括使用函数、导入模块和使用`subprocess`模块。文章讨论了各种方法的优缺点,如使用`__name__ == '__main__'`来定义执行代码,以及在不同场景下如何选择合适的方法。
摘要由CSDN通过智能技术生成

我有一个名为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作为子进程执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值