文章插图
在此示例中,您看到的代码几乎与以前相同,除了这次结果是True 。这是预实现对象的结果 。Python在内存中预先创建了某个对象子集,并将它们保存在全局命名空间中以供日常使用 。
哪些对象依赖于Python的预实现 。CPython 3.7预实现对象如下:
1.-5到256之间的整数
2.仅包含ASCII字母,数字或下划线的字符串
这背后的原因是这些变量很可能在许多程序中使用 。通过预先实现些对象,Python可以防止对一致使用的对象进行内存分配调用 。
预先实现小于20个字符且包含ASCII字母,数字或下划线的字符串 。背后的原因是假设这些字符串是某种身份:
文章插图
在这里您可以看到s1和s2都指向相同的内存地址 。如果您要引入非ASCII字母,数字或下划线组成的字符串,那么您将得到不同的结果:
文章插图
因为此示例中包含感叹号“!”,所以这些字符串不会被预先实现,并且s1和s2是内存中的不同对象 。
福利:如果您真的希望这些对象引用相同的内部对象,那么您可能需要查看sys.intern() 。文档中概述了此功能的一个用例:
预先实现的字符串对于在字典查找中获得一点性能很有用 - 如果字典中的键被预先实现,并且查找键被预先实现,则键比较(完成在散列之后)就可以通过指针来比较而不是用字符串来比较 。(来源)
预实现对象通常是混乱的来源 。请记住,如果您有任何疑问,可以随时使用id()和is确定对象是否相同 。
在Python中模拟指针仅仅因为Python中的指针本身不存在并不意味着你无法获得使用指针的好处 。实际上,可以有多种方法在Python中模拟指针 。您将在本节中学习到两种:
1.使用可变类型作为指针
2.使用自定义Python对象
好的,让我们进入正题 。
使用可变类型作为指针您已经了解过可变类型 。因为这些对象是可变的,所以您可以将它们视作指针,以此来模拟指针行为 。假设您复制了以下c代码:
文章插图
此代码将一个指针指向一个整数(*x),然后将其值增加1 。这有一个运行代码的主函数:
文章插图
在上面的代码中,将值2337赋给y,打印出当前值,将值增加1,然后打印出修改后的值 。执行此代码的输出如下:
文章插图
在Python中模仿此类行为的一种方法是使用可变类型 。考虑使用列表并修改第一个元素:
文章插图
在这里,add_one(x)访问第一个元素并将其值增加1 。通过使用列表,最终似乎已修改了该值 。那么Python中的指针确实存在吗?好吧,不 。唯一的可能是:因为列表是一种可变类型 。如果您尝试使用一个元组,则会收到错误消息:
文章插图
上面的代码演示了元组是不可变的 。因此,它不支持项目赋值 。列表不是唯一可变的类型 。在Python中模仿指针的另一种常见方法是创建字典 。
假设您有一个应用程序,您希望每次发生有趣事件时都要跟踪 。实现此目的的另一种方法是创建一个字典 并使用其中的一项作为计数器:
文章插图
在此示例中,counters字典用于跟踪函数调用的数量 。调用foo()函数后,计数器按预期增加到2 。这都是因为字典是可变类型 。
请记住,这只是模拟指针行为,并不直接映射到C或C ++中的真指针 。也就是说,这些操作在Python中会比在C或C ++中付出更多代价 。
使用Python对象使用字典是在Python中模拟指针的一种好方法,但有时您需要记住使用的密钥名称,这会很繁琐 。如果您在应用程序的各个部分都使用字典,则尤其如此 。这就是自定义Python类可以真正起到作用的地方 。
构建最后一个示例,假设您要跟踪应用程序中的指标 。创建一个类是解决那些讨厌的抽象细节的好方法:
推荐阅读
- 酷暑难耐的时候如何选择,冷饮or热茶
- Python8个最常用的内置函数
- 初学者如何区分Html5开发和前端开发
- 如何从0开始,搭建企业的实时数据中台?
- 女性喝普洱茶应注意哪些事项
- 如何辨别茶叶好坏 你知道这些吗
- 从古籍中了解古人是如何养生的
- 太极拳的基本功练习 肩臂功
- 你年四季应该如何饮茶呢
- 刹车你会踩吗?看完提升50%驾驶技巧!