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

时间:2022-10-07 23:14:55

In Python I have a module myModule.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() function of MyFormerBashScript.py? Can I even do that? How do I pass any arguments to it?

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

6 个解决方案

#1


61  

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.argv as a parameter (all code below in the same module myModule):

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

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

    现在您可以从其他模块导入并调用myModule.main(['arg1','arg2','arg3'])。

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

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

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

    并在其他地方导入并调用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 import statement is being used, so python calls that module "__main__". But if that same filename.py code 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代码视为模块(导入文件名),则python将其用作模块名称。在这两种情况下,都设置了变量__name__,并对其进行测试会告诉您代码的运行方式。

#2


18  

It depends. If the main code is protected by an if as 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 main visible to you, so you really need to import the module itself.

来自myModule import *可能不会使main显示给您,因此您确实需要导入模块本身。

#3


16  

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

#4


2  

I had the same need using argparse too. The thing is parse_args function of an argparse.ArgumentParser object 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_args as desire.

我也有同样的需要使用argparse。问题是argparse.ArgumentParser对象实例的parse_args函数默认从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_args function. Later, to use the main, you just do as Martijn tell.

关键点是将args传递给parse_args函数。后来,使用主要,你就像Martijn告诉的那样。

#5


0  

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

#6


0  

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

我在寻找的答案在这里得到了回答:如何使用python argparse与sys.argv以外的args?

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

如果以这种方式编写main.py和parse_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脚本中使用parser.parse_args([' - input','foobar.txt'])调用main()和parse参数:

# 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


61  

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.argv as a parameter (all code below in the same module myModule):

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

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

    现在您可以从其他模块导入并调用myModule.main(['arg1','arg2','arg3'])。

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

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

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

    并在其他地方导入并调用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 import statement is being used, so python calls that module "__main__". But if that same filename.py code 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代码视为模块(导入文件名),则python将其用作模块名称。在这两种情况下,都设置了变量__name__,并对其进行测试会告诉您代码的运行方式。

#2


18  

It depends. If the main code is protected by an if as 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 main visible to you, so you really need to import the module itself.

来自myModule import *可能不会使main显示给您,因此您确实需要导入模块本身。

#3


16  

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

#4


2  

I had the same need using argparse too. The thing is parse_args function of an argparse.ArgumentParser object 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_args as desire.

我也有同样的需要使用argparse。问题是argparse.ArgumentParser对象实例的parse_args函数默认从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_args function. Later, to use the main, you just do as Martijn tell.

关键点是将args传递给parse_args函数。后来,使用主要,你就像Martijn告诉的那样。

#5


0  

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

#6


0  

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

我在寻找的答案在这里得到了回答:如何使用python argparse与sys.argv以外的args?

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

如果以这种方式编写main.py和parse_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脚本中使用parser.parse_args([' - input','foobar.txt'])调用main()和parse参数:

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