python学习字符串驻留与常量折叠隐藏特性详解

下面是Python字符串的一些微妙的特性,绝对会让你大吃一惊。

案例一:

案例二:

案例三:

很好理解, 对吧?

说明:

这些行为是由于 Cpython 在编译优化时, 某些情况下会尝试使用已经存在的不可变对象而不是每次都创建一个新对象. (这种行为被称作字符串的驻留[string interning])

发生驻留之后, 许多变量可能指向内存中的相同字符串对象. (从而节省内存)

在上面的代码中, 字符串是隐式驻留的. 何时发生隐式驻留则取决于具体的实现. 这里有一些方法可以用来猜测字符串是否会被驻留

所有长度为 0 和长度为 1 的字符串都被驻留.

字符串在编译时被实现 (‘wtf' 将被驻留, 但是 ‘'.join([‘w', ‘t', ‘f']) 将不会被驻留)

字符串中只包含字母,数字或下划线时将会驻留. 所以 ‘wtf!' 由于包含 ! 而未被驻留. 可以在【地址1】找到 CPython 对此规则的实现.

当在同一行将 a 和 b 的值设置为 “wtf!” 的时候, Python 解释器会创建一个新对象, 然后同时引用第二个变量(译: 仅适用于3.7以下, 详细情况请看【地址2】). 如果你在不同的行上进行赋值操作, 它就不会“知道”已经有一个 wtf!对象 (因为 “wtf!” 不是按照上面提到的方式被隐式驻留的). 它是一种编译器优化, 特别适用于交互式环境.\

常量折叠(constant folding) 是 Python 中的一种 窥孔优化(peephole optimization) 技术. 这意味着在编译时表达式 ‘a'*20会被替换为 ‘aaaaaaaaaaaaaaaaaaaa' 以减少运行时的时钟周期. 只有长度小于 20 的字符串才会发生常量折叠. (为啥? 想象一下由于表达式 ‘a'*10**10 而生成的 .pyc 文件的大小). 相关的源码实现在【地址3】.

如果你是使用 3.7 版本中运行上述示例代码, 会发现部分代码的运行结果与注释说明相同. 这是因为在 3.7 版本中, 常量折叠已经从窥孔优化器迁移至新的 AST 优化器, 后者可以以更高的一致性来执行优化. (由 Eugene Toder 和 INADA Naoki 在 bpo-29469 和 bpo-11549 中贡献.)

(译: 但是在最新的 3.8 版本中, 结果又变回去了. 虽然 3.8 版本和 3.7 版本一样, 都是使用 AST 优化器. 目前不确定官方对 3.8 版本的 AST 做了什么调整.)

以上就是python学习字符串驻留与常量折叠隐藏特性详解的详细内容,更多关于python隐藏特的资料请关注我们其它相关文章!

(0)

相关推荐

  • python常量折叠基础知识点讲解

    1.概念 所谓常量折叠,指的是在编译时就查找并计算常量表达式,而不是在运行时再对其进行计算,从而会使运行时更加精简和快速. 2.实例 在 Python 中,我们可以使用反汇编模块(Disassembler)获取 CPython 字节码,从而更好地了解代码执行的过程. 当使用dis模块反汇编上述常量表达式时,我们会得到以下字节码: >>> import dis >>> dis.dis("day_sec = 24 * 60 * 60") 0 LOAD_C

  • python 字符串的驻留机制及优缺点

    说明 字符串驻留是一种仅保存一份相同且不可变字符串的方法.不同的值被存放在字符串驻留池中,发生驻留之后, 许多变量可能指向内存中的相同字符串对象, 从而节省内存. 原理 系统维护interned字典,记录已被驻留的字符串对象 当字符串对象a需要驻留时,先在interned检测是否存在,若存在则指向存在的字符串对象,a的引用计数减1 若不存在,则记录a到interned中 驻留时机 所有长度为 0 和长度为 1 的字符串都被驻留 字符串只在编译时进行驻留,而非运行时 a = 'hi' # a变量被

  • Python中常用的8种字符串操作方法

    拼接字符串 使用"+"可以对多个字符串进行拼接 语法格式: str1 + str2 >>> str1 = "aaa" >>> str2 = "bbb" >>> print(str1 + str2) aaabbb 需要注意的是字符串不允许直接与其他类型进行拼接,例如 >>> num = 100 >>> str1 = "hello" >

  • 举例介绍Python中的25个隐藏特性

    注:这里忽略了生成器,装饰器,交换变量等熟知技巧 1. 函数参数unpack 老生常谈的了: def foo(x, y): print x, y alist = [1, 2] adict = {'x': 1, 'y': 2} foo(*alist) # 1, 2 foo(**adict) # 1, 2 2. 链式比较操作符 >>> x = 3 >>> 1 < x < 5 True >>> 4 > x >=3 True 3. 注意

  • python学习字符串驻留与常量折叠隐藏特性详解

    下面是Python字符串的一些微妙的特性,绝对会让你大吃一惊. 案例一: 案例二: 案例三: 很好理解, 对吧? 说明: 这些行为是由于 Cpython 在编译优化时, 某些情况下会尝试使用已经存在的不可变对象而不是每次都创建一个新对象. (这种行为被称作字符串的驻留[string interning]) 发生驻留之后, 许多变量可能指向内存中的相同字符串对象. (从而节省内存) 在上面的代码中, 字符串是隐式驻留的. 何时发生隐式驻留则取决于具体的实现. 这里有一些方法可以用来猜测字符串是否会

  • Python学习之私有函数,私有变量及封装详解

    目录 什么是私有函数和私有变量 私有函数与私有变量的定义方法 Python中的封装 面向对象编程小练习 通过学习私有函数与私有变量,可以更好的完善 类的开发 ,从而丰满我们的场景与实现方案. 什么是私有函数和私有变量 私有函数与私有变量中的私有是什么意思? —> 简单理解就是独自拥有.不公开.不分享的意思.放到函数与变量中就是独自拥有的函数与独自拥有的变量,并且不公开.这样我们就理解了什么是私有函数与私有变量. 无法被实例化后的对象调用的类中的函数与变量 虽然无法被实例化后的对象调用,但是在 类

  • Python学习之线程池与GIL全局锁详解

    目录 线程池 线程池的创建 - concurrent 线程池的常用方法 线程池演示案例 线程锁 利用线程池实现抽奖小案例 GIL全局锁 GIL 的作用 线程池 线程池的创建 - concurrent concurrent 是 Python 的内置包,使用它可以帮助我们完成创建线程池的任务. 方法名 介绍 示例 futures.ThreadPoolExecutor 创建线程池 tpool=ThreadPoolExecutor(max_workers) 通过调用 concurrent 包的 futu

  • ReactDOM 隐藏特性详解

    目录 前言 React DevTools 的原理 渲染阶段 FiberRoot/FiberNode memoizedState 与 React Hooks 实践:突破 useDebugValue 的限制 useDebugValueAnywhere 的实现 特定的 devtools 总结 前言 有过 React 经验的开发者可能都使用过 React DevTools. DevTools 提供了丰富的能力:展示组件树,组件的 props 与组件中 hook 的值. React DevTools 是如

  • Python学习笔记之迭代器和生成器用法实例详解

    本文实例讲述了Python学习笔记之迭代器和生成器用法.分享给大家供大家参考,具体如下: 迭代器和生成器 迭代器 每次可以返回一个对象元素的对象,例如返回一个列表.我们到目前为止使用的很多内置函数(例如 enumerate)都会返回一个迭代器. 是一种表示数据流的对象.这与列表不同,列表是可迭代对象,但不是迭代器,因为它不是数据流. 生成器 是使用函数创建迭代器的简单方式.也可以使用类定义迭代器 下面是一个叫做 my_range 的生成器函数,它会生成一个从 0 到 (x - 1) 的数字流:

  • python学习笔记之列表(list)与元组(tuple)详解

    前言 最近重新再看python的基础知识,感觉自己还是对于这些知识很陌生,需要用的时候还是需要翻书查阅,还是先注重基础吧--我要重新把python的教程阅读一遍,把以前自己忽略的部分学习,加强练习和记忆. 现在读到了列表(list).元组(tuple).集合(set)和字典(dict)四种在python内置的重要的数据结构.我只是想记录一下列表(list)和元组(tuple)比较容易搞混的地方和阐述一遍列表(list)和元组(tuple)比较常用的一些方法. 列表(list)与元组(tuple)

  • Python字符串和字典相关操作的实例详解

    Python字符串和字典相关操作的实例详解 字符串操作: 字符串的 % 格式化操作: str = "Hello,%s.%s enough for ya ?" values = ('world','hot') print str % values 输出结果: Hello,world.hot enough for ya ? 模板字符串: #coding=utf-8 from string import Template ## 单个变量替换 s1 = Template('$x, glorio

  • python字符串string的内置方法实例详解

    下面给大家分享python 字符串string的内置方法,具体内容详情如下所示: #__author: "Pizer Wang" #__date: 2018/1/28 a = "Let's go" print(a) print("-------------------") a = 'Let\'s go' print(a) print("-------------------") print("hello"

  • python中的常量和变量代码详解

    局部和全局变量: # name='lhf' # def change_name(): # # global name # name='帅了一比' # print('change_name',name) # # # change_name() # print(name) # name='lhf' # # def change_name(): # name1='帅了一比' # name2='帅了一比' # name3='帅了一比' # print('change_name',name) # # ch

  • python不相等的两个字符串的 if 条件判断为True详解

    今天遇到一个非常基础的问题,结果搞了好久好久.....赶快写一篇博客记录一下: 本来两个不一样的字符串,在if 的条件判断中被判定为True,下面是错误的代码: test_str = 'happy' if test_str == 'good' or 'happy': #这样if判断永远是True,写法错误 print('aa') else: print('bbbb') 这是正确的代码: test_str = 'happy' if test_str == 'good' or test_str ==

随机推荐