- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在创建一个小的 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
在命令行中,我需要的两个强制参数是:
以前,我使用 argparse
和 store
操作,并使用 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/
我正在开发一个 voip 调用应用程序。我需要做的是在接到来电时将 Activity 带到前台。我在应用程序中使用 Twilio,并在收到推送消息时开始调用。 问题是我试图在接到任何电话时显示 Act
我是一名优秀的程序员,十分优秀!