python中有个相当神奇的__future__包,可以让前面的版本使用新版本的特性,比如在2.7版本中使用Unicode的str
from __future__ import unicode_literals my_str = "sample string"
这时,my_str的类型就是unicode而不是byte类型了
之前也觉得这个用法相当的神奇,无论如何想不通是如何实现的。最近面试的时候被问到了这个:
请简述__future__的原理
当然我没有回答上来。但是不服气啊,所以就看了看这东西到底是怎么实现的,于是就有了这篇博文。
我没有看之前的想法是这个库应该是在被引用之后,使用新的库版本覆盖了老的库版本。但解释不通为什么老的版本里面有新的库版本,总不可能每发布一次新版本就强制老版本的python更新版本库吧。而且也确实没有发生过这样的事情。
专门去官方的doc里面看了这个__future__的解释也没看到什么有用的。里面只是定义了一个_Future类,以及一些跟版本相关的属性和方法。
然后猛回头去看每个版本的新特性的时候发现了真正的原理,就是:
这些feature本来就已经在interpretor里面了
结论就是这么坑爹!!!!!
这样_Future定义的类就有用了,_Future类里面有三个参数OptionalRelease, MandatoryRelease, CompilerFlag
OptionnalRelease其实就是表示这个特性实际加入的版本(这个时候的interpretor已经有能力处理这个新的特性了)
MandatoryRelease表示这个特性默认被应用的版本
CompilerFlag一个二进制的码,这个才是真实传给interpretor的,作为特性开关存在的
我们引入的feature就是_Future的实例,如开头提到的unicode_literals = _Feature((2, 6, 0, "alpha", 2), (3, 0, 0, "alpha", 0), CO_FUTURE_UNICODE_LITERALS)
总结下:
__future__模块并不是引入了什么,只是打开了某些开关,让一些已经存在于interpretor的特性可以使用。
被问到这个还挂了也是无奈,写python的人套路深啊!