在Python中,我有一个模块myModule.py,其中定义了一些函数和一个main(),它接受了一些命令行参数。
我通常从bash脚本中调用此main()。现在,我想将所有内容放入一个小包装中,因此我想也许可以将我简单的bash脚本转换为Python脚本并将其放入包装中。
因此,实际上如何从MyFormerBashScript.py的main()函数调用myModule.py的main()函数?我什至可以那样做吗?如何传递任何参数?
在Python中,我有一个模块myModule.py,其中定义了一些函数和一个main(),它接受了一些命令行参数。
我通常从bash脚本中调用此main()。现在,我想将所有内容放入一个小包装中,因此我想也许可以将我简单的bash脚本转换为Python脚本并将其放入包装中。
因此,实际上如何从MyFormerBashScript.py的main()函数调用myModule.py的main()函数?我什至可以那样做吗?如何传递任何参数?
subprocess
模块调用它有意义吗?
Answers:
这只是一个功能。导入并调用它:
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__
都设置了变量,并针对该变量进行测试,以告诉您如何运行代码。
argparse
,所以当我从终端调用脚本时,我会这样做$ python myModule -a input_a -b input_b --parameterC input_c
。它如何在python代码中工作?这就是我从简单的搜索中找不到的内容。
马丁(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
AttributeError: module 'sqlacodegen' has no attribute 'main'
这取决于。如果主代码受的保护,if
例如:
if __name__ == '__main__':
...main code...
那么不,您不能让Python执行该操作,因为您无法影响自动变量__name__
。
但是,当所有代码都在一个函数中时,便可以。尝试
import myModule
myModule.main()
即使模块使用来保护自己,它也可以工作__all__
。
from myModule import *
可能main
对您不可见,因此您确实需要导入模块本身。
import sys; module.main(sys.argv);
__main__
@AaronDigulla,这是关于访问的一个很好的替代解释,这对我有所帮助,谢谢
我也有同样的需求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
函数。稍后,使用Martijn讲的就可以了。
我在搜索的答案在这里得到了答案:如何将python argparse与sys.argv以外的args一起使用?
如果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)
然后,您可以在另一个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)
假设您也尝试传递命令行参数。
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:])
argparse
而不是sys.argv
。在这种情况下会如何变化?另外,从外部脚本中,我只想传递用户输入的几个输入参数,而内部脚本的其他输入参数(myModule.py)由我进行硬编码。
*
解包的数组f(a) => f([1,2,3])
VSf(*a) => f(1,2,3)
你可以很轻松地做myModule.main(sys.argv[1], "other value", 39)
或什么的。
myModule.main()
。你试过什么了?