Python2与Python3兼容

python3写的代码如何也能在pyhon2上跑?请无论如何加上这一句,python3没有啥影响

from __future__ import absolute_import, unicode_literals, division, print_function

__future__模块提供某些将要引入的特性,python 2.7.5的__future__基本上是python3中的特性

开始

使用我们的jupyter交互式工具进行探讨,以下皆为python2

有以下内容

In [1]: import __future__

In [2]: __future__.
__future__.CO_FUTURE_ABSOLUTE_IMPORT __future__.all_feature_names
__future__.CO_FUTURE_DIVISION __future__.division
__future__.CO_FUTURE_PRINT_FUNCTION __future__.generators
__future__.CO_FUTURE_UNICODE_LITERALS __future__.nested_scopes
__future__.CO_FUTURE_WITH_STATEMENT __future__.print_function
__future__.CO_GENERATOR_ALLOWED __future__.unicode_literals
__future__.CO_NESTED __future__.with_statement
__future__.absolute_import In [2]: __future__.

可导入的功能有哪些?

In [3]: import __future__

In [4]: __future__.all_feature_names
Out[4]:
['nested_scopes',
'generators',
'division',
'absolute_import',
'with_statement',
'print_function',
'unicode_literals']

对应功能如下

division

division 新的除法特性,本来的除号/对于分子分母是整数的情况会取整,但新特性中在此情况下的除法不会取整,取整的使用//。如下可见,只有分子分母都是整数时结果不同。

In [1]: 3 / 5
Out[1]: 0 In [2]: 3 // 5
Out[2]: 0 In [3]: 3.0 / 5.0
Out[3]: 0.6 In [4]: 3.0 // 5.0
Out[4]: 0.0 In [5]: from __future__ import division In [6]: 3 / 5
Out[6]: 0.6 In [7]: 3 // 5
Out[7]: 0 In [8]: 3.0 / 5.0
Out[8]: 0.6 In [9]: 3.0 // 5.0
Out[9]: 0.0

print_function

print_function 新的print是一个函数,如果导入此特性,之前的print语句就不能用了。

In [1]: print 'test __future__'
test __future__ In [2]: from __future__ import print_function In [3]: print('test')
test In [4]: print 'test'
File "<ipython-input-4-ed4b06bfff9f>", line 1
print 'test'
^
SyntaxError: invalid syntax

unicode_literals

unicode_literals 这个是对字符串使用unicode字符

In [1]: print '目录'
鐩綍 In [2]: from __future__ import unicode_literals In [3]: print '目录'
目录

python 2.x中, 对于汉字字符串, 默认还不是采用unicode编码的, 除非在字符串前加上前缀u. 比如:

x='中国'
x
'\xd6\xd0\xb9\xfa' 这不是unicode编码
print(x)
中国
x=u'中国'
u'\u4e2d\u56fd'
print(x)
中国

python3中默认的编码采用了unicode, 并取消了前缀u. 如果代码要兼容python2/3, 就很麻烦了. 下面的两个选择都不方便:

  1. 字符串前面不加u. 这种处理方式多数情况下没有问题, 比如print输出, 但因为汉字在py2和py3的编码方式不一样, 如果进行编码转换就麻烦了.
  2. python版本判断, if sys.version < '3', 字符串不加前缀u, 如果是py2, 加上前缀u. 这样代码显得很拖沓.
  3. 现在有第3种, 比较好的方法是引入unicode_literals, from __future__ import unicode_literals , 这样在py2下, '中国'这样的字符串不用家前缀u, 也是unicode编码.

absolute_import

字面理解好像是仅仅允许绝对引用, 其实不然, 真实意思是禁用隐式相对引用:implicit relative import, 但并不会禁掉显式相对引用:explicit relative import.

举个例子, 目录结构如下,

-cake
|- __init__.py
|- icing.py
|- sponge.py
-drink
|- __init__.py
|- water.py

sponge.py 引用 icing , 有多种方法:

  1. import icing隐式相对引用, py2已强烈不推荐使用, py3已经不可用了
  2. from . import icing显式相对引用, python.org 官方虽不推荐, 但这却是事实标准
  3. from cake import icing绝对引用 , python 官方推荐.

使用 __future__ absolute_import之后, 常遇到的一个问题

PackageA
|- module1.py
|- module2.py
|- __init__.py 在module1.py中,
from __future__ import absolute_impact
from . import module2 #引入同包下的另一个module if __name__=="__main__":
print("module2 was imported in module1.")

运行会报错, ValueError: Attempted relative import in non-package.

原因分析: from . import module2 这样的写法是显式相对引用, 这种引用方式只能用于package中, 而不能用于主模块中.

因为主modulename总是为main, 并没有层次结构, 也就无从谈起相对引用了.

换句话, if __name__=="__main__": 和相对引用是不能并存的.

解决方法:

  1. module1中使用绝对引用, 这个最简单了, 但相对引用的好处也没了.
  2. 使用python -m来启动你的module1.py, 这个也不推荐.
  3. (推荐,我觉得还是和第一个差不多,只不过测试换在了另外的地方)在module1中, 加个main()函数, 然后再新建一个PackageA/entry.py做为主程序, 在entry.py中使用绝对引用来引用module1, 并调用module1.main(), 这一办法虽不完美, 但我觉得是最好的方法了.

nested_scopes

这个是修改嵌套函数或lambda函数中变量的搜索顺序,从当前函数命名空间->模块命名空间的顺序更改为了当前函数命名空间->父函数命名空间->模块命名空间,python2.7.5中默认使用

generators

生成器,对应yield的语法,python2.7.5中默认使用

with_statement

使用with关键字,python2.7.5是默认使用

运用

首先是可以做个性化的用法,比如你喜欢用print()而不是print

更重要的是基本用以下几句就可以让python2和python3有良好的兼容性了

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

Python2与Python3兼容的更多相关文章

  1. python2 和 python3兼容写法

    一:使用ImportError,Python3中将一些Python2的模块名称做了修改,需要我们做一些处理来保证代码在不同Python版本中能够正常运行 # -*- coding: utf- -*- ...

  2. Windows同时安装Python2、Python3兼容运行

    Python2.Python3可以同时安装在windows上,关键是如何有选择的运行Python2还是Python3.   指定运行版本 如果你有一个Python文件叫 hello.py,那么你可以这 ...

  3. Windows下python2与python3兼容设置

    分别安装python2与python3后,我想直接通过命令python2.pip2与python3.pip3区分: 分别进入python安装目录下,修改python.exe为python2.exe.p ...

  4. 让你的python程序同时兼容python2和python3

    python邮件列表里有人发表言论说「python3在10内都无法普及」.在我看来这样的观点有些过于悲观,python3和python2虽然不兼容,但他们之间差别并没很多人想像的那么大.你只需要对自己 ...

  5. Python - Python2与Python3的区别、转换与兼容

    区别 Python2.x与Python3.x版本区别:http://www.runoob.com/python/python-2x-3x.html 示例解读Python2和Python3之间的主要差异 ...

  6. 当同时安装Python2和Python3后,如何兼容并切换使用详解(比如pip使用)

    由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼 ...

  7. 同时安装Python2和Python3,如何兼容并切换使用详解

    由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼 ...

  8. Windows下同时安装python2和python3如何兼容版本

    引言:因学习需要把python2和python3都安装了,为了避免使用过程中混淆版本在网上找了一些解决方案,亲测可用.方法如下: 分别下载并安装Python2.x和Python3.x. 配置环境变量. ...

  9. windows下 兼容Python2和Python3

    windows下同时安装了python2和python3时,都可以配置环境变量,如果在命令行里输入python命令,windows会去环境变量里寻找Python的安装位置,如果先找到pytoon2的, ...

随机推荐

  1. javascript巧用注释保存html文本结构

    在js中,肯定会遇到js代码里面有html接口的时候,骚年们都有哪些写法? 刚学JS的写法: <script> var strHtml="<div id=\"te ...

  2. pycharm+gitee环境搭建(超详细)

    背景:本地开发代码在没有云托管的时候代码很容易丢掉,如果是小团队,这时候可以使用公司团队注册一个账号共同使用.如果是个人用于代码存储或者用于以后项目经验也推荐gitee.大的团队可以购买 环境:win ...

  3. GitHub如何删除一个代码仓库

    进入GitHub之后,点击“your repositories”查看所有的代码仓库. 在代码仓库中选择一个需要删除的,进入其详情页 在详情页中找到“setting”设置,下拉至最后可以看到删除选项. ...

  4. 【2019.11.13】SDN上机第3次作业

    参考资料:https://www.cnblogs.com/fjlinww/p/11834092.html 实验一 利用Mininet仿真平台构建如下图所示的网络拓扑,配置主机h1和h2的IP地址(h1 ...

  5. 20189220 余超《Linux内核原理与分析》第一周作业

    实验一 Linux系统简介 通过实验一主要是学习到了Linux 的历史简介,linux与windows之间的区别,主要是免费和收费,软件和支持,安全性,使用习惯,可制定性,应用范畴等.linux具有稳 ...

  6. Linux离线安装Docker

    1.从官方下载Docker安装包并上传至虚拟机 https://download.docker.com/linux/static/stable/x86_64/ 2.解压安装包 tar -xvf doc ...

  7. 实验与作业(Python)-03 Python程序实例解析(函数、循环、range、turtle)

    截止日期: 要求: 下周实验课前上交,做好后在实验课上检查可获取平时分. 做出进阶或选做的的请用清晰的标致标识出来,方便老师批改 本次作业:可提交也可不提交.作业算平时成绩. 本次作业内容量较大,请组 ...

  8. Java_jdbc 基础笔记之十一数据库连接 (通用的查询方法)

    鉴于之前的查询方法,在这里我们可以写一个通用的方法 /** * 鉴于 student.和customer查询的方法有好多相同之处,在此可以写一个通用的方法 */ public <T> T ...

  9. 利用lsof命令查找已经删除的文件来释放磁盘空间

    测试环境一台服务器/目录空间使用率达到97%,但是通过du -sh *发现实际空间没用到那么多,初步怀疑,之前删除的文件,有运行中的进程一直占用,导致空间没有释放,如图通过du -sh *发现共实际使 ...

  10. 根据 sitemap 的规则[0],当前页面 [pages/index/index] 将被索引

    sitemap 的索引提示是默认开启的,如需要关闭 sitemap 的索引提示,可在小程序项目配置文件 project.config.json 的 setting 中配置字段 checkSiteMap ...