这个Python模式有什么'隐藏陷阱'吗?

9 投票
3 回答
4338 浏览
提问于 2025-04-16 11:57

我在考虑使用这样的模式:

class Dicty(dict): 
    def __init__(self): 
         self.__dict__ = self 

d = Dicty()
d.foo = 'bar' 
print d['foo']
>>> bar 
d['foo'] = 'baz'
print d.foo
>>> 'baz'

一般来说,我更喜欢用对象属性的方式来访问数据,而不是用字典的获取和设置方式。不过,有些情况下需要像字典那样访问(比如,d['foo-bar'] = 'baz'),而我又不想为这些情况特意写一些获取和设置的方法。所以,我想同时实现字典和对象的双重功能,并且共享属性。

这种模式有没有什么需要注意的地方?

3 个回答

2

有几点需要注意。首先,如果你尝试使用字典的方法,比如 keys,现在是无法获取的。我还遇到了一些其他问题,比如无法进行序列化(pickle-able)和复制(copy-able)。

不过,我实现了一种方法,可以避免这些问题。你可以在这里看到,具体是 dictlib.py 模块 中的 AttrDict 类。这个模块还包含一个类,可以包装其他类型的映射对象,适用于那些无法被继承的情况。

3

不要直接设置 self.__dict__。应该调用父类的 __init__(self, *args, **kwargs) 方法。而且,dict 是从 object 这个类继承来的,所以你不需要特别去指定它。

10

这里有一种不那么“黑科技”的方法,可以达到同样的效果:

class Dicty(dict):
    def __getattr__(self, key):
        return self[key]

    def __setattr__(self, key, value):
        self[key] = value

觉得你的方法也可能很好用,不过像那样设置__dict__属性,看起来有点不太规范。如果其他人看到你的代码,可能会有一些疑问。

撰写回答