Python:如何使用__name__ ==’__ main__’从其他路径调用模块

Python: How to Call Module from Other Path With __name__ == '__main__'

如本回答所述,如何导入模块,可以通过以下方式导入位于另一路径中的模块:

1
2
3
import sys
sys.path.append('PathToModule')
import models.user

我的问题是:

如果其他模块的设置方式为:

1
2
if __name__ == '__main__':
    do_something()

do_something()使用argparse.ArgumentParser来处理所提供的参数?

在第一个问题/评论出现后,我添加了以下内容

我可以通过

1
2
3
4
5
sys.argv[1:] = [
   "--param1","123",
   "--param2","456",
   "--param3","111"
]

所以这个话题已经被讨论过了。

为什么我要用参数调用另一个模块?

我想能够为另一个项目做一个小的回归测试。我想通过git clone获得另一个项目,并在本地提供不同的版本,如果需要,我也可以调试。

但我不想在另一个项目中投入太多(这样分叉就没有意义)。

所以我剩下的问题是

调用另一个模块时,如何调整__name__的内容?


有多种方法可以解决这个问题。

  • 如果要导入的模块写得很好,那么它应该有单独的函数来解析命令行参数和实际执行工作。它应该是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def main(arg1, arg2):
        pass  # do something

    def parse_args():
        parser = argparse.ArgumentParser()
        ... # lots of code
        return vars(parser.parse_args())

    if __name__ == '__main__':
        args = parse_args()
        main(**args)

    在这种情况下,只需导入模块,然后使用正确的参数调用其main函数:

    1
    2
    import yourModule
    yourModule.main('foo', 'bar')

    这是最佳解决方案。

  • 如果模块没有定义这样的main功能,可以手动设置sys.argv并使用runpy.run_module执行模块:

    1
    2
    3
    4
    5
    import runpy
    import sys

    sys.argv[1:] = ['foo', 'bar']
    runpy.run_module('yourModule', run_name='__main__', alter_sys=True)

    注意,这只执行模块;它不导入模块。(即,该模块不会添加到sys.modules中,并且您没有可以与之交互的模块对象。)