In Python, can I call the main() of an imported module?
在Python中,我有一个模块mymodule.py,其中定义了一些函数和一个main(),它接受一些命令行参数。
我通常从bash脚本调用这个main()。现在,我想把所有的东西都放在一个小的包中,所以我想也许我可以把我的简单bash脚本转换成一个python脚本,然后把它放在包中。
那么,我如何从myformerbashscript.py的main()函数调用mymodule.py的main()函数呢?我能做到吗?我该如何向它传递任何参数?
这只是一个函数。导入并调用它:
1 2 3 | import myModule myModule.main() |
如果需要分析参数,有两个选项:
在
main() 中解析它们,但作为参数传入sys.argv (以下所有代码都在同一个模块myModule 中):1
2
3
4
5
6def main(args):
# parse arguments using optparse or argparse or what have you
if __name__ == '__main__':
import sys
main(sys.argv[1:])现在您可以从其他模块导入和调用
myModule.main(['arg1', 'arg2', 'arg3']) 。让
main() 接受已经解析的参数(同样是myModule 模块中的所有代码):1
2
3
4
5
6
7def main(foo, bar, baz='spam'):
# run with already parsed arguments
if __name__ == '__main__':
import sys
# parse sys.argv[1:] using optparse or argparse or what have you
main(foovalue, barvalue, **dictofoptions)在其他地方导入并调用
myModule.main(foovalue, barvalue, baz='ham') ,并根据需要传入python参数。
这里的技巧是检测模块何时被用作脚本;当您以主脚本(
马蒂金的回答是有道理的,但它遗漏了一些重要的东西,这些东西对其他人来说可能是显而易见的,但对我来说很难弄清楚。
在使用argparse的版本中,您需要在主体中包含这一行。
1 | args = parser.parse_args(args) |
通常,在脚本中使用argparse时,只需编写
1 | args = parser.parse_args() |
解析参数从命令行中找到参数。但是在这种情况下,主函数不能访问命令行参数,因此您必须告诉argparse参数是什么。
下面是一个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import argparse import sys def x(x_center, y_center): print"X center:", x_center print"Y center:", y_center def main(args): parser = argparse.ArgumentParser(description="Do something.") parser.add_argument("-x","--xcenter", type=float, default= 2, required=False) parser.add_argument("-y","--ycenter", type=float, default= 4, required=False) args = parser.parse_args(args) x(args.xcenter, args.ycenter) if __name__ == '__main__': main(sys.argv[1:]) |
假设你把它命名为mytest.py要运行它,您可以从命令行执行这些操作
1 2 3 | python ./mytest.py -x 8 python ./mytest.py -x 8 -y 2 python ./mytest.py |
分别返回
1 2 | X center: 8.0 Y center: 4 |
或
1 2 | X center: 8.0 Y center: 2.0 |
或
1 2 | X center: 2 Y center: 4 |
或者如果您想从另一个python脚本运行,可以这样做
1 2 | import mytest mytest.main(["-x","7","-y","6"]) |
哪些回报
1 2 | X center: 7.0 Y center: 6.0 |
这要看情况而定。如果主代码受
1 2 | if __name__ == '__main__': ...main code... |
不,您不能让python执行它,因为您不能影响自动变量
但是当所有的代码都在一个函数中时,那么就可以了。尝试
1 2 3 | import myModule myModule.main() |
即使在模块使用
我也同样需要使用
1 2 3 4 5 6 7 8 9 10 | def main(args): # some stuff parser = argparse.ArgumentParser() # some other stuff parsed_args = parser.parse_args(args) # more stuff with the args if __name__ == '__main__': import sys main(sys.argv[1:]) |
关键是将args传递给
我在这里搜索的答案是:如何将python argparse与sys.argv之外的参数一起使用?
如果用这种方式编写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # main.py import argparse def parse_args(): parser = argparse.ArgumentParser(description="") parser.add_argument('--input', default='my_input.txt') return parser def main(args): print(args.input) if __name__ =="__main__": parser = parse_args() args = parser.parse_args() main(args) |
然后您可以调用
1 2 3 4 5 6 7 | # temp.py from main import main, parse_args parser = parse_args() args = parser.parse_args([]) # note the square bracket # to overwrite default, use parser.parse_args(['--input', 'foobar.txt']) print(args) # Namespace(input='my_input.txt') main(args) |
假设您也在尝试传递命令行参数。
1 2 3 4 5 6 7 8 9 10 | import sys import myModule def main(): # this will just pass all of the system arguments as is myModule.main(*sys.argv) # all the argv but the script name myModule.main(*sys.argv[1:]) |