【发布时间】:2012-08-17 10:20:15
【问题描述】:
请问正确的成语是什么?
我想定义一个包含属性的对象,该对象可以(可选地)从字典初始化(字典来自 JSON;它可能不完整)。稍后我可能会通过设置器修改属性。 实际上有 13 多个属性,我希望能够使用默认的 getter 和 setter,但这似乎不适用于这种情况:
但我不想为所有 prop1... propn 编写显式描述符
另外,我想将默认分配从__init__() 移出并移到访问器中……但是我需要显式描述符。
最优雅的解决方案是什么? (除了将所有 setter 调用移出__init__() 并移入方法/类方法_make()?)
[DELETED COMMENT 使用默认描述符的 badprop 的代码是由于以前的 SO 用户的评论,他给人的印象是它给了你一个默认的 setter。但它没有 - setter 是未定义的,它必然会抛出 AttributeError。]
class DubiousPropertyExample(object):
def __init__(self,dct=None):
self.prop1 = 'some default'
self.prop2 = 'other default'
#self.badprop = 'This throws AttributeError: can\'t set attribute'
if dct is None: dct = dict() # or use defaultdict
for prop,val in dct.items():
self.__setattr__(prop,val)
# How do I do default property descriptors? this is wrong
#@property
#def badprop(self): pass
# Explicit descriptors for all properties - yukk
@property
def prop1(self): return self._prop1
@prop1.setter
def prop1(self,value): self._prop1 = value
@property
def prop2(self): return self._prop2
@prop2.setter
def prop2(self,value): self._prop2 = value
dub = DubiousPropertyExample({'prop2':'crashandburn'})
print dub.__dict__
# {'_prop2': 'crashandburn', '_prop1': 'some default'}
如果你在第 5 行 self.badprop = ... 未注释的情况下运行它,它会失败:
self.badprop = 'This throws AttributeError: can\'t set attribute'
AttributeError: 无法设置属性
[和以往一样,我阅读了关于描述符、隐式描述符、从 init 调用它们的 SO 帖子]
【问题讨论】:
-
不,它失败了,因为你没有设置一个 setter。
-
不要使用
dct={}作为默认参数...使用dct = None然后检查None并在方法内创建一个新的dict。 -
@sr2222:这太令人讨厌了,这不是问题的答案“如果没有所有属性的显式描述符,我如何编写这段代码?”如果答案是 “你不能,你需要13*2个描述符”,然后就这么说吧,不要粗鲁。如果您有比编写 13*2 描述符更好的代码习惯,请告诉我……那种代码不可扩展。因此我的问题。
-
@smci Python 将普通的 vanilla 描述符(可读写属性)视为具有属性正常行为的普通属性,根本不需要编写任何代码。描述符是获取异常行为的一种方式。
-
有可能。在几乎所有情况下,这也是毫无意义的。 90% 的情况下,直接会员访问是可行的方法。 9.99% 的时间,您想使用
__getattr__和__setattr__,如下所述。其余的是超级特殊情况,例如如果出于某种原因您想在基类中定义默认的 getter 和 setter,以便您可以覆盖子类中的行为,但由于某种原因,您不能直接在子类。我无法想象这将如何发生,但我不排除它。那么问题来了,为什么需要这个功能?
标签: python properties default propertydescriptor