jb.*_*jb. 12 python getter-setter
我对Python很陌生,所以如果这里的任何内容都很糟糕,请指出.
我有一个这个字典的对象:
traits = {'happy': 0, 'worker': 0, 'honest': 0}
Run Code Online (Sandbox Code Playgroud)
每个特征的值应该是1-10范围内的int,并且不应该允许添加新特征.我想要getter/setter所以我可以确保保留这些约束.以下是我现在制作getter和setter的方法:
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
Run Code Online (Sandbox Code Playgroud)
我读了这个网站有关的property()方法.但我没有看到一种简单的方法来利用它来获取/设置字典中的值.有一个更好的方法吗?理想情况下,我希望使用这个对象obj.traits['happy'] = 14,这将调用我的setter方法并抛出一个ValueError,因为14超过10.
unu*_*tbu 11
如果你愿意使用像那样的语法,obj['happy'] = 14你可以使用__getitem__和__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
Run Code Online (Sandbox Code Playgroud)
如果你真的想要,obj.traits['happy'] = 14那么你可以定义一个子类dict并创建obj.traits这个子类的实例.然后,子类会覆盖__getitem__和__setitem__(见下文).
PS.要dict继承,继承collections.MutableMapping和dict.否则,dict.update不会打电话给新的__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]
Run Code Online (Sandbox Code Playgroud)