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
以上将所有索引替换为另一个列表中的值。所有对该实例的引用都会看到变化; 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']
我们正在努力解决 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
以上将所有索引替换为另一个列表中的值。所有对该实例的引用都会看到变化; 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']