16

関連する複数の属性を持つクラスがあります。次に例を示します。

class SomeClass:
    def __init__(self, n=0):
        self.list = range(n)
        self.listsquare = [ x**2 for x in self.list ]

普通に作っても問題ないので、

a = SomeClass(10)

2 つのリストを取得a.listしますa.listsquare

最初に空のオブジェクトを作成し、それに 1 つの属性を割り当てたい場合は、他の属性を自動的に更新する必要があります。

b = SomeClass()
b.list = range(5,10)

私は自動的に更新されたいb.listsquareし、その逆もしたい(割り当てb.listsquareと自動更新b.list)。これは可能ですか?クラスはこれに適した選択ですか?


皆様のおかげで、私はすべての異なる答えに圧倒されています. 自分で書くことを学ぶことができるように、誰かが完全な解決策を提供できますか?

Foo私は3 つの属性をlength持つクラスを実現したいと思いlistますlistsquare

  1. もしそうなら、私は、、、をa = Foo(3)得る。a.length = 3a.list = [0, 1, 2]a.listsquare = [0, 1, 4]
  2. もしそうなら、b = Foo().list = [5, 6]私は得る。b.length = 2b.listsquare = [25, 36]
  3. もしそうなら、c = Foo().listsquare = [4, 9]私は得る。c.length = 2c.list = [2, 3]
4

4 に答える 4

25

別のプロパティの更新のために 1 つのプロパティを更新することが目的の場合 (アクセス時に下流のプロパティの値を再計算するのではなく)、プロパティ セッターを使用します。

class SomeClass(object):
    def __init__(self, n):
        self.list = range(0, n)

    @property
    def list(self):
        return self._list
    @list.setter
    def list(self, val):
        self._list = val
        self._listsquare = [x**2 for x in self._list ]

    @property
    def listsquare(self):
        return self._listsquare
    @listsquare.setter
    def listsquare(self, val):
        self.list = [int(pow(x, 0.5)) for x in val]

>>> c = SomeClass(5)
>>> c.listsquare
[0, 1, 4, 9, 16]
>>> c.list
[0, 1, 2, 3, 4]
>>> c.list = range(0,6)
>>> c.list
[0, 1, 2, 3, 4, 5]
>>> c.listsquare
[0, 1, 4, 9, 16, 25]
>>> c.listsquare = [x**2 for x in range(0,10)]
>>> c.list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
于 2013-02-16T23:53:18.747 に答える
6

絶対。ただし、代わりにプロパティを使用してください。

class SomeClass(object):
  def __init__(self, n=5):
    self.mylist = range(n)

  @property
  def listsquare(self):
    return [ x**2 for x in self.mylist ]

a = SomeClass()
a.mylist = [4, 5, 8]
print a.listsquare

プロパティ値のキャッシュは、読者の課題として残されています。

于 2013-02-16T23:34:50.637 に答える
5

Ignacio の @property ソリューションは優れていますが、listsquare を参照するたびにリストを再計算するため、コストが高くなる可能性があります。Mathew のソリューションは素晴らしいですが、今では関数呼び出しがあります。これらを「プロパティ」機能と組み合わせることができます。ここで、listsquare を生成する my_list の getter と setter を定義します ('list' とは呼べませんでした!)。

class SomeClass(object):

    def __init__(self, n=5):
        self.my_list = range(n)

    def get_my_list(self):
        return self._my_list

    def set_my_list(self, val):
        self._my_list = val
        # generate listsquare when my_list is updated
        self.my_listsquare = [x**2 for x in self._my_list]

    # now my_list can be used as a variable
    my_list = property(get_my_list, set_my_list, None, 'this list is squared')

x = SomeClass(3)
print x.my_list, x.my_listsquare
x.my_list = range(10)
print x.my_list, x.my_listsquare

これは以下を出力します:

[0, 1, 2] [0, 1, 4]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
于 2013-02-17T00:11:41.617 に答える
4

次のように、setter メソッドを使用することもできます。

class SomeClass:
    def __init__(self, n=5):
        self.set_list(range(n))

    def set_list(self, n):
        self.list = n
        self.listsquare = [ x**2 for x in self.list ]

b = SomeClass()
b.set_list(range(5,10))
于 2013-02-16T23:38:47.580 に答える