从外部模块访问argparse变量

Kur*_*aki 5 python argparse

我有4个模块:

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

我使用argparsein,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()
    
    Run Code Online (Sandbox Code Playgroud)
  • utils.py 模块:

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

    import client
    
    def run(arguments):
        user = User.new(arguments.user_id)
        client.get_user_info(user)
    
    Run Code Online (Sandbox Code Playgroud)
  • 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)
    
    Run Code Online (Sandbox Code Playgroud)

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

因此,我希望能够直接检索我得到的argparse参数utils.parse_arguments()。有没有办法做到这一点?

Mik*_*ler 5

制作一个新模块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
Run Code Online (Sandbox Code Playgroud)

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

from console_args import CONSOLE_ARGS
Run Code Online (Sandbox Code Playgroud)

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

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


小智 5

就像我的评论的建议和 Mike M\xc3\xbcller 的答案一样,下面的代码设置了一个模块级变量。
\n但是,为了防止导入时进行参数解析,我仅在parse_arguments调用一次时设置该变量。由于该变量是在此之前设置的None,因此我也仅在需要时导入该变量。
\n这样,parse_arguments仅在您调用它时运行,而不是在导入模块时运行。在您的特定情况下可能不需要它,但是当例如utils在包中使用类似的模块时,它会很方便。

\n\n

utils.py

\n\n
CONSOLE_ARGUMENTS = None\n\ndef parse_arguments():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        # Several arguments, one of which should be 'url'\n    )\n     parser.parse_args()\n    global CONSOLE_ARGUMENTS\n    CONSOLE_ARGUMENTS = parser.parse_args()\n    return CONSOLE_ARGUMENTS\n
Run Code Online (Sandbox Code Playgroud)\n\n

client.py

\n\n
def _compose_url(method):\n    from .utils import CONSOLE_ARGUMENTS\n    base_url = CONSOLE_ARGUMENTS.base_url\n    return base_url + str(method)\n
Run Code Online (Sandbox Code Playgroud)\n