Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

python - In class object, how to auto update attributes?

I have a class which has multiple attributes that are related, for example:

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

If I make an object normally that would no problem, with

a = SomeClass(10)

I will get 2 lists, a.list and a.listsquare.

Now if I want to make a empty object first, and assign one attribute to it, I want the other attributes to be automatically updated, for example if I do

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

I want b.listsquare to be automatically updated, and also the other way around (assign b.listsquare and auto update b.list). Is this possible? Is Class the right choice for this?


Thanks to you all, but I'm completely overwhelmed by all the different answers. Can anyone give a complete solution so I can learn write my own?

I would like to achieve a class Foo with 3 attributes length, list and listsquare such that:

  1. If I do a = Foo(3), I get a.length = 3, a.list = [0, 1, 2], a.listsquare = [0, 1, 4].
  2. If I do b = Foo().list = [5, 6], I get b.length = 2, b.listsquare = [25, 36].
  3. If I do c = Foo().listsquare = [4, 9], I get c.length = 2, c.list = [2, 3].
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

if updating one property due to an update on another property is what you're looking for (instead of recomputing the value of the downstream property on access) use property setters:

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]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...