1

property設定する前に値を特定のチェックを行うセッターが既に搭載されているPythonのサブクラスを書きたいと思います。

背景: 私は、すべてが負であってはならない多くの属性を持つクラスを持っています。したがって、それらをすべてプロパティにして、負でない値が設定されているかどうかを確認したいと思います。しかし、同じセッターを複数回書きたくありません。

次の例を見てください。

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?誰か助けてくれませんか?

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

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
于 2013-02-27T23:13:55.977 に答える