1

x、yとして公開したいさまざまな内部変数を持つPythonクラスがあります。簡単な例は次のとおりです。

class Vec2:
    def __init__(self):
        self.data = [0.0, 0.0]
        self.mapping = {'x':0, 'y':1}

    def __getitem__(self, index):
        return self.data[index]

    def __setitem__(self, index, value):
        self.data[index] = value

    def __getattr__(self, key):
        if key in self.mapping:
            return self.data[self.mapping[key]]
        else:
            raise AttributeError

    def _setattr__(self, key, value):
        # ?????
        pass

__getattr__は self のメンバーにアクセスするため、これは機能しないと思っていたでしょう。ただし、 a を定義しようとしない限り、すべてが機能します__setattr__- と等しくしただけでも、pass再帰が発生します。どのように実装すればよい__setattr__ですか? 特に、キーが x または y でない場合、何を呼び出す必要がありますか?

また、一般的に私の質問は、これが次のような望ましい動作を実装する正しい方法であるかどうかです。

v = Vec2()
# this
v.x = 1.0
v.y = 0.0
# or this
v[0] = 1.0
v[1] = 0.0

またはより良い代替手段があるかどうか。私はpython 2.7.5を使用しています。ありがとう!

4

2 に答える 2

3

object.__setattr__再帰を避けるために明示的に呼び出すことができます:

def __setattr__(self, key, value):
    object.__setattr__(self, key, value)
于 2014-02-11T10:42:01.073 に答える
3

__getattr__この目的でorを使用しないでください__setattr__プロパティは、タスクにより適しています。

# Inherit from object. This is important.
class Vec2(object):
    def __init__(self):
        self.data = [0.0, 0.0]

    def __getitem__(self, index):
        return self.data[index]

    def __setitem__(self, index, val):
        self.data[index] = val

    @property
    def x(self):
        return self.data[0]
    @x.setter
    def x(self, val):
        self.data[0] = val

    @property
    def y(self):
        return self.data[1]
    @y.setter
    def y(self, val):
        self.data[1] = val

__setattr__あなたの試みの問題は、 、、およびそれ自体で試行する割り当て__setattr__を含むすべての属性割り当てに対して呼び出されることです。または以外の属性を委譲することで修正できますが、プロパティの方が簡単です。また、プロパティを使用すると、無限再帰の問題を引き起こす要因の 1 つであったの属性アクセスに使用する必要がなくなります。self.dataself.mapping__setattr__object.__setattr__xyobject.__getattribute____getattr__

とは対照的に__setattr__、プロパティは、制御するアトリビュートにアクセスしようとした場合にのみトリガーされます。xプロパティは、 以外の属性へのアクセスを処理する必要はありません。またx、プロパティを記述するときに、別の属性アクセス メカニズムを使用する必要もありません。

于 2014-02-11T10:42:19.793 に答える