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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14500183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:38:39  来源:igfitidea点击:

In Python, can I call the main() of an imported module?

pythonmoduleargumentsmain

提问by Ricky Robinson

In Python I have a modulemyModule.py where I define a few functions and a main(), which takes a few command line arguments.

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

I usually call this main() from a bash script. Now, I would like to put everything into a small package, so I thought that maybe I could turn my simple bash script into a Python script and put it in the package.

我通常从 bash 脚本调用这个 main() 。现在,我想把所有东西都放在一个小包里,所以我想也许我可以把我简单的 bash 脚本变成一个 Python 脚本,然后把它放在包里。

So, how do I actually call the main()function of myModule.py from the main() functionof MyFormerBashScript.py? Can I even do that? How do I pass any argumentsto it?

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

采纳答案by Martijn Pieters

It's just a function. Import it and call it:

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

import myModule

myModule.main()

If you need to parse arguments, you have two options:

如果您需要解析参数,您有两个选择:

  • Parse them in main(), but pass in sys.argvas a parameter (all code below in the same module myModule):

    def main(args):
        # parse arguments using optparse or argparse or what have you
    
    if __name__ == '__main__':
        import sys
        main(sys.argv[1:])
    

    Now you can import and call myModule.main(['arg1', 'arg2', 'arg3'])from other another module.

  • Have main()accept parameters that are already parsed (again all code in the myModulemodule):

    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)
    

    and import and call myModule.main(foovalue, barvalue, baz='ham')elsewhere and passing in python arguments as needed.

  • 在 中解析它们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 参数。

The trick here is to detect when your module is being used as a script; when you run a python file as the main script (python filename.py) no importstatement is being used, so python calls that module "__main__". But if that same filename.pycode is treated as a module (import filename), then python uses that as the module name instead. In both cases the variable __name__is set, and testing against that tells you how your code was run.

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

回答by Aaron Digulla

It depends. If the main code is protected by an ifas in:

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

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

then no, you can't make Python execute that because you can't influence the automatic variable __name__.

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

But when all the code is in a function, then might be able to. Try

但是当所有代码都在一个函数中时,那么也许可以。尝试

import myModule

myModule.main()

This works even when the module protects itself with a __all__.

即使模块使用__all__.

from myModule import *might not make mainvisible to you, so you really need to import the module itself.

from myModule import *可能main对您不可见,因此您确实需要导入模块本身。

回答by agoebel

Assuming you are trying to pass the command line arguments as well.

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

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

回答by eguaio

I had the same need using argparsetoo. The thing is parse_argsfunction of an argparse.ArgumentParserobject instance implicitly takes its arguments by default from sys.args. The work around, following Martijn line, consists of making that explicit, so you can change the arguments you pass to parse_argsas desire.

我也有同样的需求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:])

The key point is passing args to parse_argsfunction. Later, to use the main, you just do as Martijn tell.

关键点是将 args 传递给parse_args函数。稍后,要使用 main,您只需按照 Martijn 所说的去做。

回答by barry solomon

Martijen's answer makes sense, but it was missing something crucial that may seem obvious to others but was hard for me to figure out.

Martijen 的回答是有道理的,但它遗漏了一些对其他人来说似乎很明显但我很难弄清楚的重要内容。

In the version where you use argparse, you need to have this line in the main body.

在你使用 argparse 的版本中,你需要在主体中有这一行。

args = parser.parse_args(args)

Normally when you are using argparse just in a script you just write

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

args = parser.parse_args()

and parse_args find the arguments from the command line. But in this case the main function does not have access to the command line arguments, so you have to tell argparse what the arguments are.

和 parse_args 从命令行查找参数。但是在这种情况下,main 函数无法访问命令行参数,因此您必须告诉 argparse 参数是什么。

Here is an example

这是一个例子

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

Assuming you named this mytest.py To run it you can either do any of these from the command line

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

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

which returns respectively

分别返回

X center: 8.0
Y center: 4

or

或者

X center: 8.0
Y center: 2.0

or

或者

X center: 2
Y center: 4

Or if you want to run from another python script you can do

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

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

which returns

返回

X center: 7.0
Y center: 6.0

回答by Sida Zhou

The answer I was searching for was answered here: How to use python argparse with args other than sys.argv?

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

If main.pyand parse_args()is written in this way, then the parsing can be done nicely

如果main.pyandparse_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)

Then you can call main()and parse arguments with parser.parse_args(['--input', 'foobar.txt'])to it in another python script:

然后你可以在另一个 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)