从外部模块访问argparse变量

时间:2016-12-25 15:44:37

标签: python argparse

我有4个模块:

  • entry_point.py
  • utils.py
  • runner.py
  • client.py

我在argparse中使用utils.py,我希望能够在client.py中检索其中一个参数的值。

  • 入口点模块(从控制台调用的模块):

    import utils
    def main():
        console_args = utils.parse_arguments() # Get command-line arguments
        runner.run(console_args) # The main function in the program
    
    if __name__ == '__main__':
        main()
    
  • utils.py模块:

    def parse_arguments():
        parser = argparse.ArgumentParser()
        parser.add_argument(
            # Several arguments, one of which should be 'url'
        )
        return parser.parse_args()
    
  • runner.py模块:

    import client
    
    def run(arguments):
        user = User.new(arguments.user_id)
        client.get_user_info(user)
    
  • client.py模块:

    def get_user_info(user):
        url = _compose_url('user_status')
        resp = requests.post(url, data=user.id)
    
    def _compose_url(method):
        # TODO: get base_url from console arguments
        # base_url = ?
        return base_url + str(method)
    

我不想将url作为参数传递给client.get_user_info(),因为我认为将它作为该函数的参数并不好。

所以我希望能够直接从utils.parse_arguments()检索argparse参数。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:2)

制作新模块console_args.py

"""
Parsing of command line arguments.

No other functionality should be added to this module.
The typically usage is:

>>> from console_args import CONSOLE_ARGS 
"""

def _parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        # Several arguments, one of which should be 'url'
    )
    return parser.parse_args()

CONSOLE_ARGS =  _parse_arguments()

# optional: delete function after use to prevent calling from other place
del _parse_arguments

现在您在所有模块中使用它:

from console_args import CONSOLE_ARGS

函数_parse_arguments()只会执行一次。 Python中的模块是单例,即它们仅在第一次导入时执行。 每次后续导入都将获得一个模块对象,而不执行整个导入过程,再次执行所有模块级代码。

_parse_arguments()中的下划线表示此函数不应在模块console_args.py之外使用。 调用后删除_parse_arguments将阻止在程序运行期间调用_parse_arguments()(只要不应用重新加载技巧)。

答案 1 :(得分:1)

与我的评论和MikeMüller的回答一样,下面的代码设置了一个模块级变量 但是,为了防止在导入时解析参数,我只在调用parse_arguments时设置变量。由于变量在发生之前设置为None,因此我也只在需要时导入变量 这样,parse_arguments仅在您调用它时运行,而不是在导入模块时运行。在您的具体情况下可能不需要它,但在例如像包utils这样的模块。

utils.py

CONSOLE_ARGUMENTS = None

def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        # Several arguments, one of which should be 'url'
    )
     parser.parse_args()
    global CONSOLE_ARGUMENTS
    CONSOLE_ARGUMENTS = parser.parse_args()
    return CONSOLE_ARGUMENTS

client.py

def _compose_url(method):
    from .utils import CONSOLE_ARGUMENTS
    base_url = CONSOLE_ARGUMENTS.base_url
    return base_url + str(method)