我已经开始使用这样的结构:
class DictObj(object): def __init__(self): self.d = {} def __getattr__(self, m): return self.d.get(m, None) def __setattr__(self, m, v): super.__setattr__(self, m, v)
更新:基于这个线程,我已经将DictObj实现修改为:
class dotdict(dict): def __getattr__(self, attr): return self.get(attr, None) __setattr__= dict.__setitem__ __delattr__= dict.__delitem__ class AutoEnum(object): def __init__(self): self.counter = 0 self.d = {} def __getattr__(self, c): if c not in self.d: self.d[c] = self.counter self.counter += 1 return self.d[c]
其中DictObj是一个可以通过点表示法访问的字典:
d = DictObj() d.something = 'one'
我发现它比美学更令人愉悦d['something']
.请注意,访问未定义的键会返回None而不是引发异常,这也很好.
更新:Smashery提出了一个很好的观点,mhawke扩展了更容易的解决方案.我想知道使用dict是否有任何不良副作用,而不是定义一个新字典; 如果没有,我很喜欢mhawke的解决方案.
AutoEnum是一个自动递增的枚举,使用如下:
CMD = AutoEnum() cmds = { "peek": CMD.PEEK, "look": CMD.PEEK, "help": CMD.HELP, "poke": CMD.POKE, "modify": CMD.POKE, }
两者都适合我,但我对他们感觉不熟悉.
这些实际上是不好的结构吗?
你的DictObj例子实际上很常见.如果你正在处理"类似于对象的东西",那么对象式的点符号访问可能是一个胜利.他们有固定的属性名称,只包含Python标识符中有效的字符.像数据库行或表单提交这样的东西可以有效地存储在这种对象中,使得代码更具可读性而不会超出['item access'].
实现有点受限 - 你没有得到dict,len(),comparisons,'in',iteration或nice reprs的漂亮的构造函数语法.你当然可以自己实现这些东西,但是在新式的类世界中你可以通过简单的子类化dict免费获得它们:
class AttrDict(dict): __getattr__ = dict.__getitem__ __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__
要获得default-to-None行为,只需将Python 2.5的collections.defaultdict类子类化为dict.
关于DictObj
,以下工作适合您吗?空白类将允许您随意添加或替换容器对象中的内容.
class Container(object): pass >>> myContainer = Container() >>> myContainer.spam = "in a can" >>> myContainer.eggs = "in a shell"
如果您不想在没有属性时抛出AttributeError,您对以下内容有何看法?就个人而言,我更倾向于使用dict来明确,或者使用try/except子句.
class QuietContainer(object): def __getattr__(self, attribute): try: return object.__getattr__(self,attribute) except AttributeError: return None >>> cont = QuietContainer() >>> print cont.me None
对?
这是您的DictObj类的更简单版本:
class DictObj(object): def __getattr__(self, attr): return self.__dict__.get(attr) >>> d = DictObj() >>> d.something = 'one' >>> print d.something one >>> print d.somethingelse None >>>