使用Python创建带有setter和getter的字典

1 投票
3 回答
2920 浏览
提问于 2025-04-18 11:15

我有一个类的方法用来创建一个字典。我是这样设置和获取这些值的:

 class Test(object):

    def __init__(self):
        self.config = {}


    def set_config_key(self, key, value):
        self.config[key] = value

    def _get_config_value(self, key):
       return self.config[key]

在Python 2.7中,有没有更好的方法来做到这一点?

3 个回答

0

这段代码看起来有点多余。你并没有从中获得什么封装或保护。如果你的目的是在读取列表之前对键和值进行一些处理,那这样做是可以的。不过,为了让你的代码更容易理解,最好是重载一下getitemsetitem(也就是内置的数组操作符),还有其他一些像delitem的操作。

class Test(object):

    def __init__(self):
        self.config = {}


    def __setitem__(self, key, value):
        # Do some processing here
        self.config[key] = value

    def __getitem__(self, key):
        # Do some processing here
        return self.config[key]

这样你就可以在代码中做到以下几点:

t = Test()
t['foo'] = 'bar'
print(t['foo']) # prints 'bar'

在你添加一些额外代码之前,这段代码在获取和设置值方面的表现就像一个普通的字典。

5

你可以创建一个字典的子类,这样就能以一种非常简单的方式实现和字典一样的功能:

class MyDict(dict):
    def __getattr__(self, key):
        return self.get(key)

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

>>> md = MyDict()
>>> md
{}
>>> md.foo = 1
>>> md
{'foo': 1}
5

是的,你可以使用属性访问,通过`__getattr__`和`__setattr__`这两个方法来实现:

class Test(object):
    config = None

    def __init__(self):
        self.config = {}

    def __setattr__(self, key, value):
        if self.config is None:
            # set config directly
            super(Test, self).__setattr__(key, value)
            return
        self.config[key] = value

    def __getattr__(self, key):
       return self.config[key]

这段代码的意思是,把`Test().foo`转换成`Test().config['foo']`。

示例:

>>> t = Test()
>>> t.foo = 'bar'
>>> t.foo
'bar'
>>> t.config
{'foo': 'bar'}

你也可以直接把这个映射到对象的`__dict__`,而不是`self.config`;如果你继承`dict`,你就能得到一个既可以映射又可以使用任意属性的对象:

class AttrDict(dict):
    def __init__(self, *args, **kw):
        super(AttrDict, self).__init__(*args, **kw)
        self.__dict__ = self

示例:

>>> class AttrDict(dict):
...     def __init__(self, *args, **kw):
...         super(AttrDict, self).__init__(*args, **kw)
...         self.__dict__ = self
... 
>>> foo = AttrDict()
>>> foo.bar = 'baz'
>>> foo
{'bar': 'baz'}
>>> foo.bar
'baz'

撰写回答