没有充分的理由要使用 Python 中的字典来编写此代码。这很奇怪,而且不是命名空间函数的常用方法。
这里适用的 Python 哲学是:
应该有一种——最好只有一种——明显的方法。
结合
可读性很重要。
这样做也使典型的 Python 用户难以理解和阅读。
在这种情况下,字典的好处是将字符串映射到函数并在字典中命名它们,但是模块和类都已提供此功能,熟悉 Python 的人更容易理解。
例子:
模块方法:
#cool.py
def cool():
print 'cool'
现在像使用字典一样使用模块:
import cool
#cool.__dict__['cool']()
#update - to the more correct idiom vars
vars(cool)['cool']()
类方法:
class Cool():
def cool():
print 'cool'
#Cool.__dict__['cool']()
#update - to the more correct idiom vars
vars(Cool)['cool']()
在下面的评论后编辑:
argparse 似乎很适合这个问题,所以你不必重新发明轮子。如果您决定完全自己实现它,尽管 argparse source 应该会给您一些好的方向。无论如何,以下部分似乎适用于这个用例:
15.4.4.5。超越 sys.argv
有时让 ArgumentParser 解析参数可能很有用
除了 sys.argv 的那些。这可以通过传递一个
parse_args() 的字符串列表。这对于在
互动提示:
15.4.5.1。子命令¶
ArgumentParser.add_subparsers()
许多程序将它们的功能拆分为多个子命令,例如,svn 程序可以调用子命令
比如 svn checkout、svn update 和 svn commit。
15.4.4.6。命名空间对象
让 ArgumentParser 将属性分配给
一个已经存在的对象,而不是一个新的命名空间对象。这
可以通过指定 namespace= 关键字参数来实现:
更新,这里是一个使用 argparse 的例子
strategizer = argparse.ArgumentParser()
strat_subs = strategizer.add_subparsers()
math = strat_subs.add_parser('math')
math_subs = math.add_subparsers()
math_max = math_subs.add_parser('max')
math_sum = math_subs.add_parser('sum')
math_max.set_defaults(strategy=max)
math_sum.set_defaults(strategy=sum)
strategizer.parse_args('math max'.split())
Out[46]: Namespace(strategy=<built-in function max>)
strategizer.parse_args('math sum'.split())
Out[47]: Namespace(strategy=<built-in function sum>)
我想说明我推荐 argparse 的原因
- 主要是要求使用表示选项和子选项的字符串映射到函数。
- 非常简单(通过功能填充的 argparse 模块后)。
- 使用 Python 标准库模块。这让其他熟悉 Python 的人无需深入了解实现细节即可了解您在做什么,并且对于那些不熟悉的人来说,文档也非常完善。
- 开箱即用可以利用许多额外的功能(不是最好的理由!)。
结合使用 argparse 和策略模式
对于策略模式的简单实现,这个已经很好回答了。
How to write Strategy Pattern in Python differently than example in Wikipedia?
#continuing from the above example
class MathStudent():
def do_math(self, numbers):
return self.strategy(numbers)
maximus = strategizer.parse_args('math max'.split(),
namespace=MathStudent())
sumera = strategizer.parse_args('math sum'.split(),
namespace=MathStudent())
maximus.do_math([1, 2, 3])
Out[71]: 3
sumera.do_math([1, 2, 3])
Out[72]: 6