Python 在类对象中,当您仅更改列表的一个条目时,如何自动更新属性?
我看到了一个非常相似的问题的答案: 我将在此处粘贴代码:Python 在类对象中,当您仅更改列表的一个条目时,如何自动更新属性?,python,class,attributes,Python,Class,Attributes,我看到了一个非常相似的问题的答案: 我将在此处粘贴代码: 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
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]
在此代码中,当我使用以下命令更新列表时:
>>> c.list = [1, 2, 3, 4]
c、 listsquare将相应更新:
>>> c.listsquare
[1, 4, 9, 16]
但当我尝试时:
>>> c.list[0] = 5
>>> c.list
[5, 2, 3, 4]
Listsquares未更新:
>>> c.listsquare
[1, 4, 9, 16]
当我只更改列表中的一项时,如何使listsquare自动更新?一种方法是使用一个私人助手
\u list
类,它几乎与内置的列表
类完全相同,但也有一个所有者
属性。每当一个\u列表
实例的元素被赋值时,它就可以修改其所有者
的listsquare
属性,使其保持最新。由于它仅由SomeClass
使用,因此可以将其嵌套在其中以提供更多的封装
class SomeClass(object):
class _List(list):
def __init__(self, owner, *args, **kwargs):
super(SomeClass._List, self).__init__(*args, **kwargs)
self.owner = owner
def __setitem__(self, index, value):
super(SomeClass._List, self).__setitem__(index, value)
self.owner.listsquare[index] = int(value**2)
def __init__(self, n):
self.list = SomeClass._List(self, 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)
print(c.list) # --> [0, 1, 2, 3, 4]
print(c.listsquare) # --> [0, 1, 4, 9, 16]
c.list[0] = 5
print(c.list) # --> [5, 1, 2, 3, 4]
print(c.listsquare) # --> [25, 1, 4, 9, 16]
一种方法是使用一个私人助手
\u List
类,它几乎与内置的List
类完全相同,但也有一个所有者
属性。每当一个\u列表
实例的元素被赋值时,它就可以修改其所有者
的listsquare
属性,使其保持最新。由于它仅由SomeClass
使用,因此可以将其嵌套在其中以提供更多的封装
class SomeClass(object):
class _List(list):
def __init__(self, owner, *args, **kwargs):
super(SomeClass._List, self).__init__(*args, **kwargs)
self.owner = owner
def __setitem__(self, index, value):
super(SomeClass._List, self).__setitem__(index, value)
self.owner.listsquare[index] = int(value**2)
def __init__(self, n):
self.list = SomeClass._List(self, 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)
print(c.list) # --> [0, 1, 2, 3, 4]
print(c.listsquare) # --> [0, 1, 4, 9, 16]
c.list[0] = 5
print(c.list) # --> [5, 1, 2, 3, 4]
print(c.listsquare) # --> [25, 1, 4, 9, 16]
首先,我建议您不要通过访问single list.setter来更改两个不同的属性。原因是:
>>> c.list[0] = 5
>>> c.list
[5, 2, 3, 4]
>>> c.listsquare
[1, 4, 9, 16]
不工作,是吗,您正在访问c.list.\uuu setitem\uuu方法
c.list[0] = 5
is equal to
c.list.__setitem__(0, 5)
or
list.__setitem__(c.list, 0, 5)
and as such, the list.__setitem__ method isn't the one you've implemented in your class.
但是,如果您确实想这样做,您应该重新考虑基于self.\u list创建方形列表
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
@property
def listsquare(self):
return [n ** 2 for n in self.list]
@listsquare.setter
def listsquare(self, val):
self.list = [int(pow(x, 0.5)) for x in val]
首先,我建议您不要通过访问single list.setter来更改两个不同的属性。原因是:
>>> c.list[0] = 5
>>> c.list
[5, 2, 3, 4]
>>> c.listsquare
[1, 4, 9, 16]
不工作,是吗,您正在访问c.list.\uuu setitem\uuu方法
c.list[0] = 5
is equal to
c.list.__setitem__(0, 5)
or
list.__setitem__(c.list, 0, 5)
and as such, the list.__setitem__ method isn't the one you've implemented in your class.
但是,如果您确实想这样做,您应该重新考虑基于self.\u list创建方形列表
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
@property
def listsquare(self):
return [n ** 2 for n in self.list]
@listsquare.setter
def listsquare(self, val):
self.list = [int(pow(x, 0.5)) for x in val]