たとえば、関連する複数の属性を持つクラスがあります。
_class SomeClass:
def __init__(self, n=0):
self.list = range(n)
self.listsquare = [ x**2 for x in self.list ]
_
普通にオブジェクトを作れば問題ありません
_a = SomeClass(10)
_
_a.list
_と_a.listsquare
_の2つのリストを取得します。
ここで、最初に空のオブジェクトを作成し、それに1つの属性を割り当てたい場合、たとえば、他の属性を自動的に更新する必要があります。
_b = SomeClass()
b.list = range(5,10)
_
_b.listsquare
_を自動的に更新し、その逆も行いたい(_b.listsquare
_を割り当てて_b.list
_を自動更新する)。これは可能ですか? クラスこれには正しい選択ですか?
みなさん、ありがとうございましたが、いろいろな答えに完全に圧倒されました。私が自分で書くことを学ぶことができるように、誰かが完全な解決策を与えることができますか?
次のような3つの属性Foo
、length
、およびlist
を持つクラスlistsquare
を実現したいと思います。
a = Foo(3)
を実行すると、_a.length = 3
_、_a.list = [0, 1, 2]
_、_a.listsquare = [0, 1, 4]
_が得られます。b = Foo().list = [5, 6]
を実行すると、_b.length = 2
_、_b.listsquare = [25, 36]
_が得られます。c = Foo().listsquare = [4, 9]
を実行すると、_c.length = 2
_、_c.list = [2, 3]
_が得られます。別のプロパティの更新のために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]
絶対に。ただし、代わりに property を使用してください。
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
プロパティ値のキャッシュは、読者の練習問題として残されています。
Ignacioの@propertyソリューションは素晴らしいですが、listsquareを参照するたびにリストを再計算します。これは、コストがかかる可能性があります。マシューのソリューションは素晴らしいですが、今では関数呼び出しがあります。これらを「プロパティ」関数と組み合わせることができます。ここでは、listsquareを生成するmy_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]
次のようなセッターメソッドを使用することもできます。
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))