Py学习  »  Python

如何根据某些条件自动设置python类属性值[重复]

Appyens • 6 年前 • 1675 次点击  

我有一个具有多个相关属性的类,例如:

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 .

现在,如果我想先创建一个空对象,并为其分配一个属性,我希望其他属性自动更新,例如

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

我想要 b.listsquare 自动更新,也可以通过另一种方式(分配 B.列表框 和自动更新 b.list )。这可能吗?是 等级 这个选择对吗?


谢谢大家,但我完全被各种不同的答案所淹没。有谁能给我一个完整的解决方案,让我能学会自己写吗?

我想上一堂课 Foo 有三个属性 length , list listsquare 以便:

  1. 如果我做了 a = Foo(3) ,我明白了 a.length = 3 , a.list = [0, 1, 2] , a.listsquare = [0, 1, 4]
  2. 如果我做了 b = Foo().list = [5, 6] ,我明白了 b.length = 2 , b.listsquare = [25, 36]
  3. 如果我做了 c = Foo().listsquare = [4, 9] ,我明白了 c.length = 2 , c.list = [2, 3]
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/39928
文章 [ 4 ]  |  最新文章 6 年前
Benjamin Ibhar
Reply   •   1 楼
Benjamin Ibhar    11 年前

ignacio的@property解决方案很好,但它会在每次引用listsquare时重新计算列表-这可能会变得很昂贵。Mathew的解决方案很好,但是现在有了函数调用。您可以将这些与“property”函数结合起来。在这里,我为我的清单定义了一个getter和一个setter(我只是不能称之为'list'!)生成listsquare:

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]
Matthew Adams
Reply   •   2 楼
Matthew Adams    12 年前

也可以使用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))
Ignacio Vazquez-Abrams
Reply   •   3 楼
Ignacio Vazquez-Abrams    12 年前

当然。但是用一个 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

属性值的缓存留给读者作为练习。

Ali-Akber Saifee
Reply   •   4 楼
Ali-Akber Saifee    12 年前

如果由于更新另一个属性而更新一个属性是您要查找的内容(而不是在访问时重新计算下游属性的值),请使用属性设置器:

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]