如何使用带有参数的模块?

时间:2018-11-16 13:54:57

标签: python

我有一个名为T的模块,它具有几个函数,主要部分调用这些函数。从另一个模块,我要使用此模块。主要方案如下:

"""Module T"""
def parse_args():
    parser = argparse.ArgumentParser(description='Desc')
    parser.add_argument('something')

def foo():
    pass

if __name__ == "__main__":
    args = parse_args()
    foo()

还有我要使用的其他模块:

"""Module M"""
def foo():
    pass

def do_something():
    """Where I want to use module T's main"""

我从终端使用了带有参数的模块T,并且运行良好。这个问题可能很简单,但是如何使用带参数的main呢?

2 个答案:

答案 0 :(得分:2)

向接受命令行的模块中添加run函数(或main或任何您喜欢的函数),并确保parse_args也可以选择接受任意列表:< / p>

def parse_args(args=None):
    parser = argparse.ArgumentParser(description='Desc')
    parser.add_argument('something')
    return parser.parse_args(args)

def foo():
    pass

def run(args=None):
    args = parse_args(args)
    foo()

if __name__ == "__main__":
    run()

基本上,您不必尝试模拟导入操作并注入sys.argv(这实际上是可能的),而是可以将导入过程中您感兴趣的部分剔除掉,并提供访问权限:

import T

T.run()  # Uses sys.argv
T.run(['my', 'list', '--of', 'args'])

虽然完全未经测试,但您也可以执行以下操作(请不要这样做,这只是为了好玩):

import sys
from importlib import reload

sys.argv[1:] = my_args

if 'T' in sys.modules:
    reload(sys.modules['T'])
else:
    import T

但是随后您需要在T.py中删除导入保护。除非您想实现自己的模块加载顺序,否则可以让您注入T.__name__,而不必修改导入保护:Injecting variables into an import namespace

答案 1 :(得分:2)

如果直接调用脚本,则执行if __name__ ...模式,因此真正的解决方案是在入口点调用fooif __name__ ...模式可以保护代码行免于在导入时执行。例如,这是一种非常方便的测试模式-只需将测试放在受保护的块中即可。做您要问的简单方法:

"""Module M"""
def bar():
    pass

def do_something(args):
    args = parse_args()
    module_t.foo()

如果您希望模块M完全“失控”,那么Mad Physicist的答案就是给您的。