1

我想编写一个 Python 的子类,property它已经有一个设置器,它在设置之前对值进行特定检查。

背景:我有一个具有许多属性的类,这些属性都不能是负数。所以我想将它们全部设置为属性并检查它们是否设置为非负值。但我不想多次编写同一个 setter。

请看下面的例子:

class Body(object):
  _mass = 0.
  _size = 0.

  @nonnegative
  def mass(self):
    return self._mass

  @nonnegative
  def size(self):
    return self._size

现在我想定义应该从“property”继承的“nonnegative”。我的 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?有人可以帮忙吗?

4

1 回答 1

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

“最后一个”仅用于跳过您在 init 上提供的值。保持它...最后。显然,您可以检查 attr 名称是否不是保留/特殊名称,否则

if val < 0

将检查您在初始化后设置的所有内容。

已编辑:这将在您设置值时检查非负数,而不是在您获得时。如果您想允许负值,但仅在检索时增加错误,请使用

__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
于 2013-02-27T23:13:55.977 回答