Если вы хотите использовать синтаксис, такой как 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
Если вы действительно хотите 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]