我正在使用字典对象来保存类中的实例值。我喜欢使用字典,因为我经常想同时设置或获取一堆值,并且很容易传递列表或字典来完成此操作。例如,要获取多个实例值,我只需传递一个[键列表]并返回一个{这些键的字典:值}。据我所知,如果可能的话,为每个键使用单独的属性来实现这一点需要跳过很多代码圈。
无论如何,我正在寻找这样的东西:
class SomeClass(object):
def __init__(self):
self._desc = {
'hair': 'brown'
'eyes': 'blue'
'height': 1.55
}
到目前为止,这一切都非常简单,但有些值需要特殊的“设置”条件。我的第一次尝试是这样的:
class SomeClass(object):
def __init__(self):
self._haircolor = 'blonde'
self._eyecolor = 'green'
self._desc = {
'haircolor': self.haircolor
'eyecolor': self.eyecolor
'height': 1.55
}
@property
self.haircolor(self):
return self._haircolor
@haircolor.setter
self.haircolor(self, color):
if color.lower() in ['blonde', 'brunette', 'brown', 'black', 'auburn', 'red']:
self._haircolor = color
else: raise ValueError()
# Same type of property construct for eyecolor
这不起作用。 self._desc['haircolor']
将初始化为 blonde
,但它与属性构造或 self._haircolor
属性没有动态联系。我尝试将其替换为
class SomeClass(object):
def __init__(self):
self._haircolor = 'blonde'
self._eyecolor = 'green'
self._desc = {
'haircolor': property(self.get_haircolor, self.set_haircolor)
'eyecolor': property(self.get_eyecolor, self.set_eyecolor)
'height': 1.55
}
self.get_haircolor(self):
return self._haircolor
self.set_haircolor(self, color):
if color.lower() in ['blonde', 'brunette', 'brown', 'black', 'auburn', 'red']:
self._haircolor = color
else: raise ValueError()
但这以不同的方式失败了。
print self._desc['haircolor']
将为属性对象返回一个str,并且
self._desc['haircolor'] = 'brunette'
销毁了属性对象并用字符串替换它。
我研究了一些类似的问题,例如 this one和 this one 。
然而,这两种情况都是在字典级别上运行的。问题是,当我定义自定义 dict 类时,我需要了解很多关于 dict 的信息,因为我需要预测键名称并在 setitem (第一个示例)或 dict 级别中切换它们属性对象(第二个示例)。理想情况下,我希望将 setter 与值对象本身关联起来,这样字典就不需要知道键可以引用的值有什么特殊之处。
最佳答案
Python 对象已经将属性存储在字典中,那么这里使用另一个字典有什么意义呢?只需以通常的方式存储属性(在有意义的地方使用属性),并在需要时动态构建 desc
字典即可。
class SomeClass(object):
HAIRCOLORS = set(['blonde', 'brunette', 'brown', 'black', 'auburn', 'red'])
EYECOLORS = set(['green', 'blue', 'brown', 'gray'])
def __init__(self, haircolor="blond", eyecolor="green"):
self.haircolor = haircolor
self.eyecolor = eyecolor
self.height = 1.55 # you didn't mention any validation here
@property
def haircolor(self):
return self._haircolor
@haircolor.setter
def haircolor(self, color):
color = color.lower()
if color not in self.HAICOLORS:
raise ValueError("'%s' is not a valid hair color" % color)
self._haircolor = color
# same thing for eyecolor
@property
def desc(self):
return dict(
haircolor=self.haircolor,
eyecolor=self.eyecolor,
height=self.height)
如果这是一个重复出现的模式,您最终可以编写自己的描述符:
class ChoiceDescriptor(object):
def __init__(self, key, choices):
self.key = key
self.storage = "_%s" % key
self.choices = set(choices)
def __get__(self, instance, cls=None):
if instance is None:
return self
return getattr(instance, self.storage)
def __set__(self, instance, value):
value = value.lower()
if value not in self.choices:
raise ValueError(
"'%s' is not a valid value for '%s'" % (value, self.key))
setattr(instance, self.storage, value)
class SomeClass(object):
haircolor = ChoiceDescriptor("haircolor",
['blonde', 'brunette', 'brown', 'black', 'auburn', 'red'])
eyecolor = ChoiceDescriptor("eyecolor",
['green', 'blue', 'brown', 'gray'])
关于python - 如何在Python中将类似属性的对象与字典值关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20561002/