python - 你能用内部方法完全替换一个对象吗?

python - Can you replace an object completely by internal method?

我们正在努力解决 python 3 中的以下问题:我们定义了一个 class,它继承自 list。我们想要合并一种方法,通过该方法它可以将自身更新为此 class.

的新实例

一些非常简单的代码来说明我们的意思:

class test(list):
    def update(self):
        self = test(['a','b','c','d'])

x = test([1,2,3])
x.update()
print(x)

这段代码returns原始列表[1,2,3],表明对象x确实没有被更新。有没有办法让对象完全更新自己?我们需要它来处理不同长度的列表。

self 只是另一个变量。方法对象会导致当前实例被分配给该名称(就像其他值被分配给其他函数参数一样),但与其他名称一样,分配给它们将仅更改名称所指的对象.引用同一对象的其他名称,如 x 不会随着 .

而改变

那是因为Python代码中的名称是just like tags,而self = <something else>就像把旧实例的标签放到另一个对象上。仍然附加到旧对象的任何 other 标签都不会被移动!因为 x 仍然引用旧实例,所以不会看到您将 self 标记放在另一个对象上。

您的 update() 方法需要 return 新对象(以便调用者可以更新其引用以指向新对象),或就地更改列表(此时 所有对该对象的引用 将看到相同的更改。

返回对象意味着调用者负责用return值做一些事情:

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 也会更改索引 0。如果您分配给 slice,您可以一次更改多个索引。 identity 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

以上将所有索引替换为另一个列表中的值。所有对该实例的引用都会看到变化; selfx 以及任何其他此类引用。

这意味着什么的演示:

>>> 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']