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

时间:2013-01-24 11:23:52

标签: python module arguments main

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

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

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

7 个答案:

答案 0 :(得分:79)

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

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__都已设置,对此进行测试会告诉您代码的运行方式。

答案 1 :(得分:24)

Martijen的回答是有道理的,但它遗漏了一些对他人来说显而易见的重要事情,但我很难弄明白。

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

args = parser.parse_args(args)

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

即可
args = parser.parse_args()

和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:])

假设你将此命名为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

答案 2 :(得分:20)

这取决于。如果主代码受if保护,如:

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

然后不,你不能让Python执行,因为你不能影响自动变量__name__

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

import myModule

myModule.main()

即使模块使用__all__保护自身,也可以使用此功能。

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

答案 3 :(得分:2)

我也有同样的需要使用argparse。 问题是parse_args对象实例的argparse.ArgumentParser函数默认从sys.args隐式获取其参数。在Martijn行之后的工作包括明确表达,因此您可以根据需要更改传递给parse_args的参数。

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传递给parse_args函数。 后来,使用main,你就像Martijn告诉的那样。

答案 4 :(得分:0)

假设您也尝试传递命令行参数。

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:])

答案 5 :(得分:0)

我在寻找的答案在这里得到了解答: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)

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

# 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)

答案 6 :(得分:0)

我遇到了这个问题,我无法调用文件 Main() 方法,因为它被这些点击选项修饰,例如:

# @click.command()
# @click.option('--username', '-u', help="Username to use for authentication.")

当我删除这些装饰/属性时,我可以从另一个文件成功调用 Main() 方法。

from PyFileNameInSameDirectory import main as task
task()