正确使用字典值的 getter/setter
我对 Python 还很陌生,所以如果这里有任何不好的地方,请指出。
我有一个带有这个字典的对象:
traits = {'happy': 0, 'worker': 0, 'honest': 0}
每个特征的值应该是1-10范围内的整数,并且不允许添加新的特征。我想要 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
我在 此网站上阅读了有关 property()
方法。但我没有看到一种简单的方法来利用它来获取/设置字典中的值。有更好的方法吗?理想情况下,我希望该对象的用法为 obj.traits['happy'] = 14
,这将调用我的 setter 方法并抛出 ValueError,因为 14 大于 10。
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}
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
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您愿意使用像
obj['happy'] = 14
这样的语法,那么您可以使用__getitem__
和__setitem__
:如果您确实想要
obj.traits['happy'] = 14
那么您可以定义dict
的子类并使obj.traits
成为该子类的实例。然后,子类将覆盖
__getitem__
和__setitem__
(见下文)。附言。要子类
dict
,请同时继承collections.MutableMapping
和dict
。否则,dict.update
将不会调用新的__setitem__
。If you are willing to use syntax like
obj['happy'] = 14
then you could use__getitem__
and__setitem__
:If you really do want
obj.traits['happy'] = 14
then you could define a subclass ofdict
and makeobj.traits
an instance of this subclass.The subclass would then override
__getitem__
and__setitem__
(see below).PS. To subclass
dict
, inherit from bothcollections.MutableMapping
, anddict
. Otherwise,dict.update
would not call the new__setitem__
.我首先想到的是一些明显的提示:
.keys()
方法(而不是if key not in self.traits.keys()
code> 使用如果 key 不在 self.traits
中)。更改后,您的代码可能如下所示:
经过上述 我没有彻底检查你的代码的正确性 - 可能还有其他一些问题。
Some obvious tips come to my mind first:
.keys()
method when checking for existence of some key (instead ofif key not in self.traits.keys()
useif key not in self.traits
).Your code could look like this after above changes:
Ps. I did no check the correctness of your code thoroughly - there may be some other issues.
执行此操作的自然方法是使用对象而不是字典,并设置类的
__slots__
。执行此操作的自然方法是使用对象而不是字典,以便您可以编写作为类一部分的 getter/setter 逻辑,并将它们包装为属性。由于所有这些属性都以相同的方式工作,因此我们可以进行一些重构来编写代码,在给定属性名称的情况下生成属性。
以下可能是过度设计的:
The natural way to do this is to use an object instead of a dictionary, and set the class'
__slots__
.The natural way to do this is to use an object instead of a dictionary, so that you can write getter/setter logic that's part of the class, and wrap them up as properties. Since all these properties will work the same way, we can do some refactoring to write code that generates a property given an attribute name.
The following is probably over-engineered: