Python ArgParse Subparsers 并链接到正确的函数

标签 python parameters command-line-arguments argparse

我正在创建一个小的 Python 脚本来管理不同类别的服务器(FTP、HTTP、SSH 等)

在每种类型的服务器上,我们可以执行不同类型的操作(部署、配置、检查等)

我有一个基 Server 类,然后为继承自此的每种类型的服务器创建一个单独的类:

class Server:
    ...
    def check():
        ...

class HTTPServer(Server):
    def check():
        super(HTTPServer, self).check()
        ...
class FTPServer(Server):
    def check():
        super(FTPServer, self).check()
        ...

示例命令行可能是:

my_program deploy http

在命令行中,我需要的两个强制参数是:

  1. 要执行的操作
  2. 要创建/管理的服务器类型

以前,我使用 argparsestore 操作,并使用 dict 将命令行选项与实际类匹配和函数名称。例如:

types_of_servers = {
    'http': 'HTTPServer',
    'ftp': 'FTPServer',
    ...
}

valid_operations = {
    'check': 'check',
    'build': 'build',
    'deploy': 'deploy',
    'configure': 'configure',
    'verify': 'verify',
}

(在我的实际代码中,valid_operations 并不是一个简单的 1:1 映射。)

然后使用相当糟糕的代码来创建正确类型的对象,并调用正确的类。

然后我想我应该使用 argparse 的 subparsers 功能来代替它。所以我将每个操作(检查、构建、部署等)都设为 subparser .

通常,我可以将每个子命令链接到一个特定的函数,并让它调用它。但是,我不想只调用通用的 check() 函数 - 我需要首先创建正确类型的对象,然后在其中调用适当的函数对象。

是否有好的或 Pythonic 的方法来做到这一点?最好是不涉及大量硬编码或设计不当的 if/else 循环?

最佳答案

如果您准备为每个命令使用子解析器,我会做这样的事情。使用 argparse 的类型支持来调用一个函数,该函数查找您要实例化的类并返回它。

然后使用 getattr() 动态调用该实例上的方法

import argparse

class Server:
    def check(self):
        return self.__class__.__name__

class FooServer(Server):
    pass

class BarServer(Server):
    pass


def get_server(server):
    try:
        klass = globals()[server.capitalize()+'Server']
        if not issubclass(klass, Server):
            raise KeyError

        return klass()
    except KeyError:
        raise argparse.ArgumentTypeError("%s is not a valid server." % server)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='command')

    check = subparsers.add_parser('check')
    check.add_argument('server', type=get_server)

    args = parser.parse_args()

    print getattr(args.server, args.command)()

输出看起来像这样:

$ python ./a.py check foo
FooServer
$ python ./a.py check bar
BarServer
$ python ./a.py check baz
usage: a.py check [-h] server
a.py check: error: argument server: baz is not a valid server.

关于Python ArgParse Subparsers 并链接到正确的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6262788/

相关文章:

c - 数组指针作为参数传递给其他函数时会更改值

delphi - delphi SDI中创建新表单时传递参数

linux - 为什么 GCC(和其他工具)不遵循 GNU 命令选项约定准则?

tomcat7 上的 java 命令行参数

python - 如何使用shutil复制文件并给出前缀日期

python - CountVectorizer max_features 如何处理具有相同频率的 ngram?

python - "Broken"以 UTF-8 编码的 unicode 字符串?

Python:为什么 int 和 list 函数参数的处理方式不同?

python - 内存增长虽然被覆盖

下载完整目录命令行psftp