将参数传递给python应用程序?

Posted

技术标签:

【中文标题】将参数传递给python应用程序?【英文标题】:Pass arguments to python application? 【发布时间】:2021-01-10 16:44:55 【问题描述】:

我有一个 Python3 应用程序,我想使用 Ubuntu 18.04 终端向它传递一些参数:

python3 app/app.py -af app/annotation_file.json -em app/model/ -output_dir app/new_model/ -n_iter 100

我正在尝试使用 argparse:

if __name__ == "__main__":
    from argparse import ArgumentParser

    parser = ArgumentParser()
    parser.add_argument("-af", "--annotation_file",
                        dest="main", default=None,
                        help="Path to annotated file")
    parser.add_argument("-em", "--existing_model_path",
                        dest="main", default=None,
                        help="Retrain existing model or train from scratch")
    parser.add_argument("-output_dir", "--output_dir_to_save_model",
                        dest="main", default="/app/model",
                        help="Path to save newly generated NER model")
    parser.add_argument("-n_iter", "--num_iter",
                        dest="main", default=100,
                        help="Number of iterations to train the model")

    args = parser.parse_args()
    print(args)
    main(args)

输出:

Namespace(main='100')
Namespace(main='100')

但我没有得到输出。 如何将上述所有命名参数传递给我的 main() 函数?

【问题讨论】:

python中没有特殊的main @MadPhysicist 我的代码中有一个 main() 函数。我想从终端传递参数。 然后显示。 请记住,dest 是每个选项最终所在的命名空间中的变量。我不知道您为什么将它们都称为main。也许删除dest='main' 部分? 请出示 MCVE。我基本上已经回答了你的问题。 【参考方案1】:

好的,所以,您可以将参数传递给函数,但是您的每一行解析器都会将输入数据保存到:

dest="main"

每个新的 parser.add_argument 行都会覆盖您的主变量。

如果您的 main() 函数有四个参数,请将每个 parser.add_argument() 行的 dest="" 行更改为指向不同的变量,然后调用您的 main() 函数:

main(args.arg1, args.arg2, args.arg3, args.arg4)

其中 arg-n 是您新创建的每个不同的变量。

例如,给定您的代码:

if __name__ == "__main__":
    from argparse import ArgumentParser

    parser = ArgumentParser()
    parser.add_argument("-af", "--annotation_file",
                        dest="arg1", default=None,
                        help="Path to annotated file")
    parser.add_argument("-em", "--existing_model_path",
                        dest="arg2", default=None,
                        help="Retrain existing model or train from scratch")
    parser.add_argument("-output_dir", "--output_dir_to_save_model",
                        dest="arg3", default="/app/model",
                        help="Path to save newly generated NER model")
    parser.add_argument("-n_iter", "--num_iter",
                        dest="arg4", default=100,
                        help="Number of iterations to train the model")

    args = parser.parse_args()
    print(args)
    main(args.arg1, args.arg2, args.arg3, args.arg4)

【讨论】:

【参考方案2】:

我会清理你的解析器定义(我删除了dest,并修复了短选项标志):

parser = ArgumentParser()
parser.add_argument("-a", "--af", "--annotation_file",
                    help="Path to annotated file")
parser.add_argument("-e", "--em", "--existing_model_path",
                    help="Retrain existing model or train from scratch")
parser.add_argument(+-o", "--output_dir", "--output_dir_to_save_model",
                    default="/app/model",
                    help="Path to save newly generated NER model")
parser.add_argument("-n", "--n_iter", "--num_iter",
                    default=100,
                    help="Number of iterations to train the model")

args = parser.parse_args()
print(args)

现在您将在 namespace 中看到所有 4 个参数,并且可以通过名称访问它们

args.n_iter
args.output_dir

通常dest 取自双破折号标志之一。您最终会将args 传递给main() 的事实与argparse 无关。您通过为所有 4 个参数提供相同的 dest 来搞乱您的解析器,结果您只能看到一个的值。

如文档所述,您可以轻松获得字典版本

vars(args)

https://docs.python.org/3/library/argparse.html#dest

对于可选参数操作,dest 的值通常是从选项字符串中推断出来的。 ArgumentParser 通过获取第一个长选项字符串并剥离初始 -- 字符串来生成 dest 的值。如果未提供长选项字符串,则 dest 将通过剥离初始 - 字符从第一个短选项字符串派生。

【讨论】:

以上是关于将参数传递给python应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何将两个参数传递给由 ajax 函数调用的 python 函数?

Windows 没有将命令行参数传递给从 shell 执行的 Python 程序

将文件作为参数传递给 Docker 容器

dajaxice:将参数传递给 python 函数

将文件x中指定的函数作为命令行参数传递给python中的文件y的最佳方法

在 Eclipse(Pydev) 中将命令行参数传递给 Python 脚本