正确使用字典的getter/setter方法 [英] Correct usage of a getter/setter for dictionary values

查看:80
本文介绍了正确使用字典的getter/setter方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Python还是很陌生,所以如果这里有什么不好的事情,请指出.

I'm pretty new to Python, so if there's anything here that's flat-out bad, please point it out.

我有一个带有此字典的对象:

I have an object with this dictionary:

traits = {'happy': 0, 'worker': 0, 'honest': 0}

每个特征的值应为1到10的整数,并且不应添加新的特征.我要使用getter/setter,所以我可以确保保留这些约束.这是我现在制作吸气剂和吸气剂的方法:

The value for each trait should be an int in the range 1-10, and new traits should not be allowed to be added. I want getter/setters so I can make sure these constraints are being kept. Here's how I made the getter and setter now:

def getTrait(self, key):
    if key not in self.traits.keys():
        raise KeyError

    return traits[key]

def setTrait(self, key, value):
    if key not in self.traits.keys():
        raise KeyError

    value = int(value)

    if value < 1 or value > 10:
        raise ValueError

    traits[key] = value

我在此网站上阅读了有关property()方法的信息.但是我没有找到一种简单的方法来利用它来获取/设置字典中的值.有一个更好的方法吗?理想情况下,我希望此对象的用法为obj.traits['happy'] = 14,它将调用我的setter方法并由于14超过10而抛出ValueError.

I read on this website about the property() method. But I don't see an easy way to make use of it for getting/setting the values inside the dictionary. Is there a better way to do this? Ideally I would like the usage of this object to be obj.traits['happy'] = 14, which would invoke my setter method and throw a ValueError since 14 is over 10.

推荐答案

如果您愿意使用obj['happy'] = 14这样的语法,则可以使用__getitem____setitem__:

If you are willing to use syntax like obj['happy'] = 14 then you could use __getitem__ and __setitem__:

def __getitem__(self, key):
    if key not in self.traits.keys():
        raise KeyError
    ... 
    return traits[key]

def __setitem__(self, key, value):
    if key not in self.traits.keys():
        raise KeyError
    ...
    traits[key] = value

如果您确实想要obj.traits['happy'] = 14,则可以定义dict的子类,并将obj.traits用作此子类的实例. 然后,子类将覆盖__getitem____setitem__(请参见下文).

If you really do want obj.traits['happy'] = 14 then you could define a subclass of dict and make obj.traits an instance of this subclass. The subclass would then override __getitem__ and __setitem__ (see below).

PS.要继承dict的子类,请同时继承collections.MutableMappingdict.否则,dict.update不会调用新的__setitem__.

PS. To subclass dict, inherit from both collections.MutableMapping, and dict. Otherwise, dict.update would not call the new __setitem__.

import collections
class TraitsDict(collections.MutableMapping,dict):
    def __getitem__(self,key):
        return dict.__getitem__(self,key)
    def __setitem__(self, key, value):
        value = int(value)
        if not 1 <= value <= 10:
            raise ValueError('{v} not in range [1,10]'.format(v=value))
        dict.__setitem__(self,key,value)
    def __delitem__(self, key):
        dict.__delitem__(self,key)
    def __iter__(self):
        return dict.__iter__(self)
    def __len__(self):
        return dict.__len__(self)
    def __contains__(self, x):
        return dict.__contains__(self,x)

class Person(object):
    def __init__(self):
        self.traits=TraitsDict({'happy': 0, 'worker': 0, 'honest': 0})

p=Person()
print(p.traits['happy'])
# 0

p.traits['happy']=1
print(p.traits['happy'])
# 1

p.traits['happy']=14
# ValueError: 14 not in range [1,10]

这篇关于正确使用字典的getter/setter方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆