python调用使用argparser的模块

Posted

技术标签:

【中文标题】python调用使用argparser的模块【英文标题】:python calling a module that uses argparser 【发布时间】:2017-11-27 19:49:44 【问题描述】:

这可能是一个愚蠢的问题,但我有一个 python 脚本,当前使用 argparser 接受一堆争论,我想将此脚本作为模块加载到另一个 python 脚本中,这很好。但我不确定如何调用模块,因为没有定义函数;如果我只是从 cmd 调用它,我还能像以前一样调用它吗?

这是子脚本:

import argparse as ap
from subprocess import Popen, PIPE

parser = ap.ArgumentParser(
    description='Gathers parameters.')
parser.add_argument('-f', metavar='--file', type=ap.FileType('r'), action='store', dest='file',
                    required=True, help='Path to json parameter file')
parser.add_argument('-t', metavar='--type', type=str, action='store', dest='type',
                    required=True, help='Type of parameter file.')
parser.add_argument('-g', metavar='--group', type=str, action='store', dest='group',
                    required=False, help='Group to apply parameters to')
# Gather the provided arguements as an array.
args = parser.parse_args()

... Do stuff in the script

这是我要从中调用子脚本的父脚本;它还使用 arg 解析器并执行一些其他逻辑

from configuration import parameterscript as paramscript

# Can I do something like this?
paramscript('parameters/test.params.json', test)

在配置目录中,我还创建了一个 init.py 文件,该文件为空。

【问题讨论】:

【参考方案1】:

parse_args 的第一个参数是参数列表。默认情况下它是None,这意味着使用sys.argv。所以你可以像这样安排你的脚本:

import argparse as ap

def main(raw_args=None):
    parser = ap.ArgumentParser(
        description='Gathers parameters.')
    parser.add_argument('-f', metavar='--file', type=ap.FileType('r'), action='store', dest='file',
                        required=True, help='Path to json parameter file')
    parser.add_argument('-t', metavar='--type', type=str, action='store', dest='type',
                        required=True, help='Type of parameter file.')
    parser.add_argument('-g', metavar='--group', type=str, action='store', dest='group',
                        required=False, help='Group to apply parameters to')
    # Gather the provided arguements as an array.
    args = parser.parse_args(raw_args)
    print(vars(args))


# Run with command line arguments precisely when called directly
# (rather than when imported)
if __name__ == '__main__':
    main()

然后在其他地方:

from first_module import main

main(['-f', '/etc/hosts', '-t', 'json'])

输出:

'group': None, 'file': <_io.TextIOWrapper name='/etc/hosts' mode='r' encoding='UTF-8'>, 'type': 'json'

【讨论】:

为了避免手动拆分参数列表:main('-f /etc/hosts -t json'.split()) 或者如果拆分需要更复杂:import shlex; main(shlex.split('-f /etc/hosts -t json -g "special group name with spaces"'))(shlex 在标准库中。)【参考方案2】:

可能有一种更简单、更 Pythonic 的方式来做到这一点,但这里有一种使用 subprocess 模块的可能性:

示例:

child_script.py

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-n", "--name", help="your name")
args = parser.parse_args()

print("hello there ").format(args.name)

然后另一个 Python 脚本可以像这样调用该脚本:

calling_script.py:

import subprocess

# using Popen may suit better here depending on how you want to deal
# with the output of the child_script.
subprocess.call(["python", "child_script.py", "-n", "Donny"])

执行上述脚本会得到以下输出:

"hello there Donny"

【讨论】:

从这里的经验来看,使用 subprocess 运行 python 而不是导入模块会导致问题。子流程中的 FileNotFoundException 会变成返回代码,您必须检查和处理的代码比没有子流程的情况要多。 “除了 FileNotFoundError:raise”变成带有子进程的意大利面条。这是冰山一角。为了你未来的自己和同事,不要这样做。【参考方案3】:

其中一个选项是将其称为子进程调用,如下所示:

import subprocess
childproc = subprocess.Popen('python childscript.py -file yourjsonfile')
op, oe = childproc.communicate()
print op

【讨论】:

以上是关于python调用使用argparser的模块的主要内容,如果未能解决你的问题,请参考以下文章

Python模块之argparse

python中argparse模块简单使用

python学习之argparse模块的使用

python 命令行参数——argparse模块的使用

python argparse模块

Python 命令行工具 argparse 模块使用详解