我想创建一个简单的一次性Python对象来保存一些命令行选项.我想做这样的事情:
options = ?????? options.VERBOSE = True options.IGNORE_WARNINGS = False # Then, elsewhere in the code... if options.VERBOSE: ...
当然我可以使用字典,但options.VERBOSE
更容易阅读和输入options['VERBOSE']
.
我以为我应该能做到
options = object()
,因为它object
是所有类对象的基类型,因此应该类似于没有属性的类.但它不起作用,因为使用创建的对象object()
没有__dict__
成员,因此无法向其添加属性:
options.VERBOSE = True Traceback (most recent call last): File "", line 1, in AttributeError: 'object' object has no attribute 'VERBOSE'
什么是最简单的"pythonic"方法来创建可以这种方式使用的对象,最好不必创建额外的帮助类?
该集合模块已长出了namedtuple功能在2.6:
import collections opt=collections.namedtuple('options','VERBOSE IGNORE_WARNINGS') myoptions=opt(True, False) >>> myoptions options(VERBOSE=True, IGNORE_WARNINGS=False) >>> myoptions.VERBOSE True
一个namedtuple是不变的,所以当你创建你只能指定字段值.
在早期的Python版本中,您可以创建一个空类:
class options(object): pass myoptions=options() myoptions.VERBOSE=True myoptions.IGNORE_WARNINGS=False >>> myoptions.IGNORE_WARNINGS,myoptions.VERBOSE (False, True)
根据您的要求,我会说自定义课程是您最好的选择:
class options(object): VERBOSE = True IGNORE_WARNINGS = True if options.VERBOSE: # ...
要完成,另一种方法是使用单独的模块,即options.py
封装您的选项默认值.
options.py
:
VERBOSE = True IGNORE_WARNINGS = True
然后,在main.py
:
import options if options.VERBOSE: # ...
这具有从脚本中删除一些混乱的功能.默认值易于查找和更改,因为它们在自己的模块中被封锁.如果以后您的应用程序增长,您可以轻松地从其他模块访问这些选项.
这是我经常使用的模式,如果您不介意您的应用程序比单个模块增长更大,那么我们会非常谨慎地推荐这种模式.或者,从自定义类开始,如果您的应用程序增长到多个模块,则稍后扩展到模块.
为什么不使用optparse:
from optparse import OptionParser [...] parser = OptionParser() parser.add_option("-f", "--file", dest="filename", help="write report to FILE", metavar="FILE") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") (options, args) = parser.parse_args() file = options.filename if options.quiet == True: [...]
如果您坚持不必定义类,则可以滥用某些现有类.大多数对象属于没有dict的"new-style"类,但函数可以具有任意属性:
>>> x = lambda: 0 # any function will do >>> x.foo = 'bar' >>> x.bar = 0 >>> x.xyzzy = x >>> x.foo 'bar' >>> x.bar 0 >>> x.xyzzyat 0x6cf30>
一个问题是函数已经有一些属性,所以dir(x)有点乱:
>>> dir(x) ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'foo', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'xyzzy']
我用attrdict:
class attrdict(dict): def __init__(self, *args, **kwargs): dict.__init__(self, *args, **kwargs) self.__dict__ = self
根据你的观点,你可能认为它既是一个大块头,也可能是一个非常聪明的人.但无论你怎么想,它确实能够制作漂亮的代码,并与dict兼容:
>>> ad = attrdict({'foo': 100, 'bar': 200}) >>> ad.foo 100 >>> ad.bar 200 >>> ad.baz = 'hello' >>> ad.baz 'hello' >>> ad {'baz': 'hello', 'foo': 100, 'bar': 200} >>> isinstance(ad, dict) True