这个 Python 模式有什么需要注意的地方吗?

9
我考虑使用的模式是:
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'

通常,我更喜欢使用对象属性访问的语义,而不是字典的get/set访问,但有些情况下需要使用类似字典的访问方式(例如:d['foo-bar'] = 'baz'),我不想为这些情况编写特殊的getter和setter方法,因此,同时具有字典和对象的双重行为,并共享属性。

上述模式是否存在任何问题?


1
请参见:https://dev59.com/mnA75IYBdhLWcg3w7tt6 - Josh Lee
1
isinstance(dict, object)。你不需要从object继承。而且实现方式也很粗糙。同时,这可能是Python中像属性一样访问字典键的问题的重复 - user395760
1
用这种方式创建的对象可以轻松进行pickle,但是用被接受答案建议的方式创建的对象则不行。 - Gearoid Murphy
3个回答

10

这里有一种更少“hacky”的方法来实现相同的效果:

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

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

认为你的方法也可以正常工作,但是像那样设置__dict__属性在样式上似乎有些不可靠,并且肯定会在其他人阅读您的代码时引起一些问题。


4
你应该捕获并翻译 KeyError__getattr__ 应该抛出 AttributeError - Cat Plus Plus
2
如果你要这样做,最好只需执行 __getattr__ = __getitem____setattr__ = __setitem__。更简单,少了一个函数调用。 - kindall
@GearoidMurphy。我对支持container.attribute语法的数据容器进行腌制很感兴趣。这些对象为什么不能被腌制?您有任何支持腌制的替代解决方案建议吗? - Amelio Vazquez-Reina
使用“slacy”在他的问题中描述的方法,它可以正常工作。 - Gearoid Murphy
似乎无法处理嵌套对象。如果字典中的键有空格怎么办? - viveksinghggits
显示剩余2条评论

3
不要设置self.__dict__。在超类上调用__init__(self, *args, **kwargs)。此外,dict继承自object,因此您不需要指定它。

2

有几件事情需要注意。首先,如果您尝试使用类似于keys的字典方法,现在将无法获取它。我遇到了其他一些问题,例如可pickle和可copy。

但是,我已经实现了一些可以解决这些问题的东西。您可以在此处查看,它是dictlib.py模块中的AttrDict类。该模块还包含一个类,可以包装另一个映射样式对象,在无法进行子类化的情况下使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接