在Python中,可以调用导入模块的main()吗?

136 投票
7 回答
192706 浏览
提问于 2025-04-17 13:31

在Python中,我有一个叫做myModule.py的模块,里面定义了一些函数和一个main()函数,这个main()函数可以接收一些命令行参数。

我通常是通过一个bash脚本来调用这个main()函数。现在,我想把所有东西放到一个小的里,所以我想也许可以把我的简单bash脚本变成一个Python脚本,并把它放进这个包里。

那么,我到底该怎么从MyFormerBashScript.py的main()函数中调用myModule.py的main()函数呢?我能做到吗?我又该如何把任何参数传递给它呢?

7 个回答

39

这要看情况。如果主要的代码被一个 if 保护起来,比如:

if __name__ == '__main__':
    ...main code...

那么不行,你无法让 Python 执行那部分代码,因为你无法影响自动变量 __name__

但是如果所有的代码都在一个函数里,那你可能就能做到。试试这个:

import myModule

myModule.main()

即使模块用 __all__ 进行了保护,这个方法也能奏效。

from myModule import * 可能不会让你看到 main,所以你真的需要直接导入整个模块。

59

Martijen的回答很有道理,但缺少了一些关键的内容,这对其他人来说可能很明显,但我自己却很难理解。

在使用argparse的版本中,你需要在主程序里加上这一行。

args = parser.parse_args(args)

通常,当你在脚本中使用argparse时,你只需要写

args = parser.parse_args()

然后parse_args就会从命令行中找到参数。但在这种情况下,主函数无法访问命令行参数,所以你必须告诉argparse这些参数是什么。

这里有一个例子

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,要运行它,你可以在命令行中输入以下任意一个命令

python ./mytest.py -x 8
python ./mytest.py -x 8 -y 2
python ./mytest.py 

这将分别返回

X center: 8.0
Y center: 4

或者

X center: 8.0
Y center: 2.0

或者

X center: 2
Y center: 4

如果你想从另一个python脚本中运行它,你可以这样做

import mytest
mytest.main(["-x","7","-y","6"]) 

这将返回

X center: 7.0
Y center: 6.0
161

这只是一个函数。你只需要导入它并调用它:

import myModule

myModule.main()

如果你需要解析参数,有两种选择:

  • main() 函数中解析参数,但要把 sys.argv 作为一个参数传入(以下所有代码都在同一个模块 myModule 中):

    def 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 模块中):

    def 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 参数。

这里的关键是要检测你的模块是否被当作脚本使用;当你运行一个 Python 文件作为主脚本时(python filename.py),没有使用 import 语句,所以 Python 会把这个模块称为 "__main__"。但是如果同样的 filename.py 代码被当作模块使用(import filename),那么 Python 会把它当作模块名来处理。在这两种情况下,变量 __name__ 都会被设置,通过对比这个变量,你就可以知道你的代码是如何运行的。

撰写回答