在Python中我有一个模块 myModule.py,我在其中定义了一些函数和一个 main(),它需要一些命令行参数。
我通常从bash脚本中调用main()。现在,我想将所有内容放入一个小的包中,所以我想也许我可以将我的简单bash脚本变成Python脚本并将其放入包中。
那么,我如何从MyFormerBashScript.py的main()函数调用myModule.py 的main()函数?我甚至可以这样做吗?如何将任何参数传递给它?
答案 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)
在使用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.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)
然后你可以调用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()