返回介绍

3.7 不可变映射类型

发布于 2024-02-05 21:59:48 字数 1434 浏览 0 评论 0 收藏 0

标准库里所有的映射类型都是可变的,但有时候你会有这样的需求,比如不能让用户错误地修改某个映射。3.4.2 节提到过 Pingo.io,它里面就有个现成的例子。Pingo.io 里有个映射的名字叫作 board.pins,里面的数据是 GPIO 物理针脚的信息,我们当然不希望用户一个疏忽就把这些信息给改了。因为硬件方面的东西是不会受软件影响的,所以如果把这个映射里的信息改了,就跟物理上的元件对不上号了。

从 Python 3.3 开始,types 模块中引入了一个封装类名叫 MappingProxyType。如果给这个类一个映射,它会返回一个只读的映射视图。虽然是个只读视图,但是它是动态的。这意味着如果对原映射做出了改动,我们通过这个视图可以观察到,但是无法通过这个视图对原映射做出修改。示例 3-9 简短地对这个类的用法做了个演示。

示例 3-9 用 MappingProxyType 来获取字典的只读实例 mappingproxy

>>> from types import MappingProxyType
>>> d = {1:'A'}
>>> d_proxy = MappingProxyType(d)
>>> d_proxy
mappingproxy({1: 'A'})
>>> d_proxy[1]  ➊
'A'
>>> d_proxy[2] = 'x'  ➋
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment
>>> d[2] = 'B'
>>> d_proxy  ➌
mappingproxy({1: 'A', 2: 'B'})
>>> d_proxy[2]
'B'
>>>

➊ d 中的内容可以通过 d_proxy 看到。

➋ 但是通过 d_proxy 并不能做任何修改。

➌ d_proxy 是动态的,也就是说对 d 所做的任何改动都会反馈到它上面。

因此在 Pingo.io 中我们是这样用它的:Board 的具体子类会提供一个包含针脚信息的私有映射成员,然后通过公开属性 .pins 把这个映射暴露给 API 的客户,而 .pins 属性其实就是用 mappingproxy 实现的。一旦这样写好了,客户就不能对这个映射进行任何意外的添加、移除或者修改操作。8

8为了照顾 Python 2.7,现实中的 Pingo.io 没有借用 MappingProxyType 来实现这个功能,因为它只在 Python 3.3 里才有。

到了这里,我们对标准库中的大多数映射类型都有了一些了解,下面让我们移步到集合类型。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文