web-dev-qa-db-ja.com

Python:プロパティゲッターに複数の引数を渡す方法

次の例を考えてみましょう。

_class A:
    @property
    def x(self): return 5
_

したがって、もちろんa = A(); a.xを呼び出すと_5_が返されます

しかし、プロパティxを変更できるようにしたいと想像してください。
このように、例えば:

_class A:
    @property
    def x(self, neg = False): return 5 if not neg else -5
_

a = A(); a.x(neg=True)で呼び出します

xは_'int' object is not callable_として評価されるため、TypeError:_5_が発生しますが、これは非常に正常です。

したがって、可能な場合は、プロパティゲッターに複数の引数を渡す方法を知りたいと思います。

50
Rizo

デコレーターとしてpropertyを使用するためにhaveをしないことに注意してください。古い方法で非常に喜んで使用し、プロパティに加えて個々のメソッドを公開できます。

class A:
    def get_x(self, neg=False):
        return -5 if neg else 5
    x = property(get_x)

>>> a = A()
>>> a.x
5
>>> a.get_x()
5
>>> a.get_x(True)
-5

これはあなたがそれで何をしているのかに応じて良いアイデアかもしれませんし、そうでないかもしれません(しかし、私がレビューしているコードでこのパターンに出くわした場合、コメントに優れた正当性が見られると思います)

55
ncoghlan

プロパティの目的を完全に理解していないと思います。

プロパティxを作成する場合は、obj.x()の代わりにobj.xを使用してアクセスします。プロパティを作成した後、基になる関数を直接呼び出すことは簡単にできません。

引数を渡す場合は、メソッドにget_xという名前を付け、プロパティにしないでください。

def get_x(self, neg=False):
    return 5 if not neg else -5

セッターを作成する場合は、次のようにします。

class A:
    @property
    def x(self): return 5

    @x.setter
    def x(self, value): self._x = value
34
ThiefMaster

プロパティは、関連するオブジェクトのみに依存する必要があります。一部の外部パラメーターを使用する場合は、メソッドを使用する必要があります。

16
Sepp

2番目の例では、a.x()を関数であるかのように使用しています:a.x(neg=True)。これを念頭に置いて、なぜそれを関数として定義しないのですか?

11
NPE

私はこの質問が古いことを知っていますが、参考のために、そのような引数でプロパティを呼び出すことができます:

a = A()
assert a.x == 5
assert A.x.fget(a, True) == -5

他の人が述べたように、これはお勧めできません。

5
Campi

この特定のケースでは、基になる関数を呼び出す2つのプロパティを定義できます。

class A:
    @property
    def x(self):
        return self._x(neg = False)

    @property
    def x_neg(self):
        return self._x(neg = True)

    def _x(self, neg):
        return 5 if not neg else -5
3
Kim SJ