如何在Python中将函数,列表等作为args传递给argparse?

时间:2020-04-25 17:23:09

标签: python multithreading module arguments argparse

我有以下有效的脚本,并且我试图避免在同一模块中使用'__main__'

def download():
    urls = \
        [
            'https://ipleak.net/json',
            'https://httpbin.org/get'
        ] * 4

    downloads = asyn.init_download(urls, "json")
    return downloads

def pprint_json(d):
    print(json.dumps(d, indent=4, sort_keys=True))

def multiprocess_list(n_pools, func, list):
    executor = concurrent.futures.ProcessPoolExecutor(n_pools)
    futures = [executor.submit(func, item) for item in list]
    concurrent.futures.wait(futures)

if __name__ == '__main__':
    multiprocess_list(4, pprint_json, download())

顾名思义,download()函数使用urlsasyncio异步下载aiohttp

我想从“全局”的任何地方执行multiprocess_list

def multiprocess_list(n_pools, func, list):
    executor = concurrent.futures.ProcessPoolExecutor(n_pools)
    futures = [executor.submit(func, item) for item in list]
    concurrent.futures.wait(futures)

def main(args):
    parser = argparse.ArgumentParser(description="Multiprocessing a list.")
    parser.add_argument("-n", "--n_pools", type=int, required=True)
    parser.add_argument("-f", "--function", required=True)
    parser.add_argument("-l", "--list", required=True)
    args = parser.parse_args(args)

    multiprocess_list(args.n_pools, args.function, args.list)

if __name__ == '__main__':
    import sys
    main(sys.argv[1:])

将上面的模块导入到其他任何python文件中,并可能像这样运行它:(尽管不起作用)

def download():
    urls = \
        [
            'https://ipleak.net/json',
            'https://httpbin.org/get'
        ] * 4

    downloads = asyn.init_download(urls, "json")
    return downloads

def pprint_json(d):
    print(json.dumps(d, indent=4, sort_keys=True))

mp.main(["-n", 4, "-f", pprint_json, "-l", download()])

这给了我一个错误:

if not arg_string[0] in self.prefix_chars: TypeError: 'int' object is not subscriptable

因此,将一个参数传递为要运行的函数,将另一个参数传递为列表或返回诸如download()之类的列表的函数。

  • 这可以在python中完成吗?
  • 如果是,有人可以解释一下吗?
  • 我的方法正确吗?还是我完全迷失了?

NB :我的解释器使用Python3.8,我是python的新手,请耐心一点。

1 个答案:

答案 0 :(得分:1)

Argparse需要一个字符串列表,并且可能会阻塞其他类型。如果您引用4是否有效?

mp.main(["-n", "4", "-f", pprint_json, "-l", download()])

pprint_jsondownload()的结果也应该是字符串,以使其正常工作。

这种创建替代argv的方法并不总是很疯狂,但是在您的情况下,为什么要调用main()为您解析args?为什么不使用适当的参数直接调用multiprocess_list()

使用main()的原因是因为将来我可能会添加除multiprocess_list()之外的更多功能

然后,您可以在从Python调用脚本时直接调用它们,而不用创建另一个参数来选择其中一个。您仍然可以使用main()来从命令行解析args。

下一个错误TypeError: 'function' object is not subscriptable

啊,那也不是字符串。在那种情况下,我也不希望它可以从命令行运行。你有那么多工作吗?

您可以尝试类似

mp.main(["-n", "4", "-f", "pprint_json", "-l", download()])

但是main()必须能够以某种方式将函数名称解释为函数。也许像

multiprocess_list(args.n_pools, getattr(foo, args.function), args.list)

其中foo是保留可选功能的模块。