你可以用内部方法完全替换一个对象吗?

时间:2018-06-21 14:30:56

标签: python object methods replace internal

我们正在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确实尚未更新。有没有办法让一个对象完全更新自身?我们需要它来处理不同长度的列表。

1 个答案:

答案 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

以上内容将所有索引替换为另一个列表中的值。对实例的所有引用都会看到更改; 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']