我们正在python 3中努力解决以下问题:我们定义了一个类,该类继承自list
。我们希望合并一个方法,通过它可以将自身更新为此类的新实例。
一些非常简单的代码来说明我们的意思:
class test(list):
def update(self):
self = test(['a','b','c','d'])
x = test([1,2,3])
x.update()
print(x)
此代码返回原始列表[1,2,3]
,该列表显示对象x确实尚未更新。有没有办法让一个对象完全更新自身?我们需要它来处理不同长度的列表。
答案 0 :(得分:4)
self
是另一个变量。方法对象导致将当前实例分配给该名称(就像将其他值分配给其他函数参数一样),但是像其他名称一样,分配给它们将仅更改名称所引用的对象。引用同一对象的其他名称,例如x
,也不会随之更改。
这是因为Python代码中的名称为just like tags,而self = <something else>
就像获取旧实例的标签并将其放在另一个对象上一样。仍附加到旧对象上的所有 other 标签都不会移动!由于x
仍引用旧实例,因此不会看到您将self
标记放在另一个对象上。
您的update()
方法需要返回新对象(以便调用者可以更新其引用以指向新对象),或就地更改列表(在对该对象的所有引用将看到相同的更改。
返回对象意味着调用者负责使用返回值进行操作:
class test(list):
def update(self):
return test(['a','b','c','d'])
x = test([1,2,3])
x = x.update() # re-bind `x` to point to the new object.
print(x)
或者您可以分配给列表本身的索引;这会更改列表的内容指向的内容。您可以像使用其他引用一样使用self
,因此x[0] = 5
会更改索引0,self[0] = 5
也将更改。而且,如果您分配给 slice ,则可以一次更改多个索引。 身份切片 [:]
使您可以一次更改所有索引,还可以分配更多或更少的值来增加或缩小列表。分配给self[:]
会更改所有索引,并允许您更改所有索引以指向任意数量的不同值。
所以:
class test(list):
def update(self):
self[:] = ['a', 'b', 'c', 'd']
x = test([1,2,3])
x.update()
print(x) # The x reference to the same list will see the change too
以上内容将所有索引替换为另一个列表中的值。对实例的所有引用都会看到更改; self
和x
以及其他任何此类引用。
这是什么意思的演示:
>>> class test(list):
... def update(self):
... self[:] = ['a', 'b', 'c', 'd']
...
>>> x = test([1, 2, 3])
>>> y = x # another reference to the same object
>>> x
[1, 2, 3]
>>> y
[1, 2, 3]
>>> x.update() # update the list in-place
>>> x # visible here
['a', 'b', 'c', 'd']
>>> y # and here!
['a', 'b', 'c', 'd']