Python的dictionary视图对象是其赋值natu的例外吗

2024-04-27 03:51:19 发布

您现在位置:Python中文网/ 问答频道 /正文

根据this question on Stack Overflow,Python中的赋值总是按值进行的,因此不能更改原始源代码。例如(来自同一个问题)

locs = [ [1], [2] ]
for loc in locs:
    loc = []

print locs
# prints => [ [1], [2] ]

但是,dictionary视图对象显示相反的行为

bike = {"Manufacturer":"Honda","Model":"CBR","cc":250,"price":70,"mileage":74}

keys = bike.keys()
print(keys)

bike["tyres"] = 2
print(keys)

这是输出:

dict_keys(['mileage', 'price', 'Model', 'Manufacturer', 'cc'])
dict_keys(['cc', 'Manufacturer', 'tyres', 'mileage', 'Model', 'price'])

是否可以将它们视为按值赋值的例外?如果是,在Python3中还有哪些例外?你知道吗


Tags: modelkeysthispricelocdictccquestion
1条回答
网友
1楼 · 发布于 2024-04-27 03:51:19

不,这也不例外。没有为字典视图分配任何内容。视图是显式的documented as being dynamic

They provide a dynamic view on the dictionary’s entries, which means that when the dictionary changes, the view reflects these changes.

这是因为它们只存储对原始字典的引用,并以不同于dictionary API的方式直接访问键、值或(key, value)对。你知道吗

如果需要,可以在对象上构建自己的视图,但请注意,这样的对象仍然需要对原始对象的引用:

from collections.abc import Sequence

class ListReversedView(Sequence):
    def __init__(self, lst):
        self._lst = lst
    def __getitem__(self, idx):
        if idx < 0:
            new = (-idx) - 1
        else:
            new = len(self) - idx - 1
            if new < 0:
                raise IndexError(new)
        return self._lst[new]
    def __len__(self):
        return len(self._lst)
    def __repr__(self):
        return f"[{', '.join(map(repr, self))}]"

上面的示例为您提供了列表内容的不同视图;对列表的更改反映在该对象提供的“视图”中。对Python的赋值模型不需要做任何特殊的处理;赋值仍然只是对对象的引用,这个视图对象中的_lst属性也不例外:

>>> foo = ['spam', 'ham', 'eggs']
>>> view = ListReversedView(foo)
>>> view
['eggs', 'ham', 'spam']
>>> foo[-1] = 'bacon'
>>> view
['bacon', 'ham', 'spam']

循环回到列表循环;您仍然可以将其分配回列表对象本身;重新绑定名称可能不起作用,但重新绑定索引就可以了:

for index in range(len(locs)):
    locs[index] = []

总之,Python对象都存在于一个堆中,名称和属性只是引用这些对象。可以存在多个引用,并且每个这样的引用都将看到对对象所做的更改(如果允许的话)。赋值只改变特定引用所指向的内容。Dict视图在这里也不例外,它们只是继续引用创建它们的字典。你知道吗

您可能想了解Python模型;我强烈推荐Facts and myths about Python names and values article by Ned Batchelder。你知道吗

相关问题 更多 >