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

Ric*_*son 70 python program-entry-point arguments module

在Python中我有一个模块 myModule.py,我在其中定义了一些函数和一个main(),它接受一些命令行参数.

我通常从bash脚本中调用main().现在,我想将所有内容放入一个小包中,所以我想也许我可以将我的简单bash脚本转换为Python脚本并将其放入包中.

那么,我如何 MyFormerBashScript.py 的main()函数实际调用 myModule.py 的main()函数?我甚至可以这样做吗?我如何传递任何参数

Mar*_*ers 96

这只是一个功能.导入并调用它:

import myModule

myModule.main()
Run Code Online (Sandbox Code Playgroud)

如果需要解析参数,则有两个选项:

  • 解析它们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:])
    
    Run Code Online (Sandbox Code Playgroud)

    现在您可以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)
    
    Run Code Online (Sandbox Code Playgroud)

    并导入并调用myModule.main(foovalue, barvalue, baz='ham')其他地方并根据需要传入python参数.

这里的技巧是检测模块何时被用作脚本; 当您运行python文件作为主脚本(python filename.py)时,没有import使用任何语句,因此python调用该模块"__main__".但是如果将相同的filename.py代码视为module(import filename),则python将其用作模块名称.在这两种情况下,__name__都会设置变量,并对其进行测试会告诉您代码的运行方式.

  • 当然。但是输入参数呢?我使用argparse,所以当我从终端调用脚本时,我执行$ python myModule -a input_a -b input_b --parameterC input_c`。它如何在python代码中工作?这是我从简单的搜索中找不到的。 (3认同)

小智 33

Martijen的回答是有道理的,但它缺少一些对他人来说可能显而易见的重要事情,但我很难弄明白.

在使用argparse的版本中,您需要在主体中包含此行.

args = parser.parse_args(args)
Run Code Online (Sandbox Code Playgroud)

通常,当您在脚本中使用argparse时,您只需编写

args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

和parse_args从命令行中查找参数.但在这种情况下,main函数无法访问命令行参数,因此您必须告诉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:])
Run Code Online (Sandbox Code Playgroud)

假设您将此命名为mytest.py要运行它,您可以从命令行执行任何操作

python ./mytest.py -x 8
python ./mytest.py -x 8 -y 2
python ./mytest.py 
Run Code Online (Sandbox Code Playgroud)

分别返回

X center: 8.0
Y center: 4
Run Code Online (Sandbox Code Playgroud)

要么

X center: 8.0
Y center: 2.0
Run Code Online (Sandbox Code Playgroud)

要么

X center: 2
Y center: 4
Run Code Online (Sandbox Code Playgroud)

或者如果你想从另一个python脚本运行,你可以做

import mytest
mytest.main(["-x","7","-y","6"]) 
Run Code Online (Sandbox Code Playgroud)

返回

X center: 7.0
Y center: 6.0
Run Code Online (Sandbox Code Playgroud)

  • 这正是我所需要的 - 非常感谢您提供有用的附录 (2认同)

Aar*_*lla 22

这取决于.如果主代码受以下内容的保护if:

if __name__ == '__main__':
    ...main code...
Run Code Online (Sandbox Code Playgroud)

那么不,你不能让Python执行,因为你不能影响自动变量__name__.

但是当所有代码都在一个函数中时,那么也许能够.尝试

import myModule

myModule.main()
Run Code Online (Sandbox Code Playgroud)

即使模块使用a保护自身,这也可以工作__all__.

from myModule import *可能无法让main您看到,因此您确实需要导入模块本身.


Sid*_*hou 6

我正在寻找的答案在这里得到了解答:How to use python argparse with args other than sys.argv?

如果main.pyparse_args()是这样写的话,那么解析就可以很好的完成了

# 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)
Run Code Online (Sandbox Code Playgroud)

然后你可以在另一个 python 脚本中调用main()并解析parser.parse_args(['--input', 'foobar.txt'])它的参数:

# 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)
Run Code Online (Sandbox Code Playgroud)