我想写一个Python property
的子类,它已经有一个setter,它在设置之前对值进行了特定的检查。
背景:我有一个具有许多属性的类,所有属性都不能为负。所以我想将它们全部用于属性并检查它们是否设置了非负值。但我不想多次写同一个setter。
请看下面的例子:
class Body(object):
_mass = 0.
_size = 0.
@nonnegative
def mass(self):
return self._mass
@nonnegative
def size(self):
return self._size
现在我想定义“非负”,它应该从“属性”继承。我的ansatz覆盖了__set__
方法,但我被卡住了:
class nonnegative(property):
def __set__(self, obj, value):
if value < 0:
raise ValueError, 'value must not be negative'
### then set the attribute to value, but how?
### how can I know the name of the attribute?
或许我应该覆盖fset
?还是setter
?有人可以帮忙吗?
答案 0 :(得分:0)
并不像这样简单:
class Body(object):
def __init__(self):
self._mass = 0.
self._size = 0.
self.last = True
def __setattr__(self, name, val):
if 'last' in self.__dict__:
if val < 0:
raise ValueError('value must not be negative')
return
self.__dict__[name] = val
def mass(self):
return self._mass
def size(self):
return self._size
“last”仅用于跳过您在init上提供的值。保持...最后。 显然,您可以检查attr名称是不是保留/特殊名称还是
if val < 0
将检查你在init之后设置的所有内容。
编辑:这将在您设置值时检查非负数,而不是在您获得时。如果要允许负值,但仅在检索时出现错误,请使用
__getattr__
或者(对于abarnert)经典的方式,但你必须为每个属性写setter / getter:
class Body(object):
def __init__(self):
self._mass = 0.
self._size = 0.
@property
def mass(self):
return self._mass
@mass.setter
def mass(self, value):
if value < 0:
raise ValueError('value must not be negative')
self._mass = value
@mass.getter
def mass(self):
return self._mass