2016-12-25 109 views
3

argparse变量我有4个模块:访问外部模块

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

我用utils.py​​,我希望能够检索其中一个arg的值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参数。有没有办法做到这一点?

+0

你可以做的参数的模块('entry_point'或'utils')宽的变量(设置为'None'直到参数解析),并在'_compose_url'中导入。但这可能有点模糊。或者,在'get_user_info'周围创建一个包含'url'参数的一次性包装函数。或者重新思考你的函数,因为'get_user_info' * *确实需要一个'base_url'。 – Evert

回答

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) 
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()

+0

这样,参数解析在导入时完成。这可能不是你想要的。 – Evert

+0

@Evert请你详细说明一下吗? –

+0

@KurtBourbaki运行'import utils'或类似的时候,'_parse_arguments()'也会运行。通常,在脚本中,没关系,但如果您只想导入“utils”模块而不解析任何参数,则可能会产生意外的结果。 – Evert