python便利贴:python2-3兼容的代码

2024-01-19 13:58

本文主要是介绍python便利贴:python2-3兼容的代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

Table of Contents

支持包: python-future and six

关键语法

raising exceptions

defining exception and exception chaining

catching exceptions

Division

Long integers

Octal constants

Backtick repr

Unicode String/Byte String/BaseString

Imports relative to a package

Dictionaries

xrange vs range

map

raw_input & input

More


 


版权所有:013-2016 Python Charmers Pty Ltd, Australia.

作者: Ed Schofield.

许可:Creative Commons Attribution.

pdf版本: http://python-future.org/compatible_idioms.pdf

视频版本: http://www.youtube.com/watch?v=KOqk8j11aAI&t=10m14s

这个笔记列举了写面向未来的代码(即同时支持python2和3)的一些惯例

对小版本:

  • Python 2: 2.6+
  • Python 3: 3.3+

支持包: python-future and six

python-future是python2和python3之间缺少的兼容层, 其允许你使用一个单一的,干净的python 3.x-compatible基础代码去同时支持python 2和3。这样产生的开销是最小的(minimal overhead)。

我们使用pip install future可以import如下包:

import future
import builtins
import past
import futurize             
import pasteurize         

 

目的相同共同相似的包还有python six,可以通过pip install six来安装,安装后,可import如下包:

import six

关键语法

  • print

python2 only:

[wlin@wlin rc_ci]$ ipython2
Python 2.7.5 (default, May 31 2018, 09:41:32) 
In [2]: print 'Hello' 
Hello

for both:

[wlin@wlin python_compatible]$ cat print.py 
from __future__ import print_function
print('hello','world')
[wlin@wlin python_compatible]$ python2 print.py 
hello world
[wlin@wlin python_compatible]$ python3 print.py 
hello world

 

  • raising exceptions

python2 only:

[wlin@wlin python_compatible]$ ipython2 
Python 2.7.5 (default, May 31 2018, 09:41:32) In [1]: raise ValueError, "dodgy value"
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-640428d25114> in <module>()
----> 1 raise ValueError, "dodgy value"ValueError: dodgy valueIn [3]: import sysIn [4]: traceback = sys.exc_info()[2]In [5]: raise ValueError, "dodgy value", traceback
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-91d00a6d59b2> in <module>()
----> 1 raise ValueError, "dodgy value", tracebackValueError: dodgy value

for both:

carawangs-MacBook-Pro:python_compatible carawang$ cat raise_error.py 
raise ValueError('dodgy value')#from future.utils import raise_with_traceback
#raise_with_traceback(ValueError("dodgy value"))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 raise_error.py 
Traceback (most recent call last):File "raise_error.py", line 1, in <module>raise ValueError('dodgy value')
ValueError: dodgy value
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 raise_error.py 
Traceback (most recent call last):File "raise_error.py", line 1, in <module>raise ValueError('dodgy value')
ValueError: dodgy valuecarawangs-MacBook-Pro:python_compatible carawang$ cat raise_error.py 
#raise ValueError('dodgy value')from future.utils import raise_with_traceback
raise_with_traceback(ValueError("dodgy value"))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 raise_error.py 
Traceback (most recent call last):File "raise_error.py", line 4, in <module>raise_with_traceback(ValueError("dodgy value"))File "<string>", line 7, in raise_with_traceback
ValueError: dodgy value
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 raise_error.py 
Traceback (most recent call last):File "raise_error.py", line 4, in <module>raise_with_traceback(ValueError("dodgy value"))File "/usr/local/lib/python3.7/site-packages/future/utils/__init__.py", line 446, in raise_with_tracebackraise exc.with_traceback(traceback)
ValueError: dodgy value
  • defining exception and exception chaining

python3 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat exception_class.py 
class DatabaseError(Exception):passclass FileDataBase:def __init__(self, filename):try:self.file = open(filename)except IOError as exc:raise DatabaseError('Failed to open') from excFileDataBase("non_existent_file.txt")carawangs-MacBook-Pro:python_compatible carawang$ vi exception_class.py 
YouCompleteMe unavailable: unable to load Python.
Press ENTER or type command to continue
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 exception_class.py 
Traceback (most recent call last):File "exception_class.py", line 7, in __init__self.file = open(filename)
FileNotFoundError: [Errno 2] No such file or directory: 'non_existent_file.txt'The above exception was the direct cause of the following exception:Traceback (most recent call last):File "exception_class.py", line 11, in <module>FileDataBase("non_existent_file.txt")File "exception_class.py", line 9, in __init__raise DatabaseError('Failed to open') from exc
__main__.DatabaseError: Failed to open
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 exception_class.py File "exception_class.py", line 9raise DatabaseError('Failed to open') from exc^
SyntaxError: invalid syntax
for both:
carawangs-MacBook-Pro:python_compatible carawang$ cat exception_class.py 
from future.utils import  raise_fromclass DatabaseError(Exception):passclass FileDataBase:def __init__(self, filename):try:self.file = open(filename)except IOError as exc:raise_from(DatabaseError('Failed to open'), exc)FileDataBase("non_existent_file.txt")
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 exception_class.py 
Traceback (most recent call last):File "exception_class.py", line 9, in __init__self.file = open(filename)
FileNotFoundError: [Errno 2] No such file or directory: 'non_existent_file.txt'The above exception was the direct cause of the following exception:Traceback (most recent call last):File "exception_class.py", line 13, in <module>FileDataBase("non_existent_file.txt")File "exception_class.py", line 11, in __init__raise_from(DatabaseError('Failed to open'), exc)File "/usr/local/lib/python3.7/site-packages/future/utils/__init__.py", line 403, in raise_fromexec(execstr, myglobals, mylocals)File "<string>", line 1, in <module>
__main__.DatabaseError: Failed to open
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 exception_class.py 
Traceback (most recent call last):File "exception_class.py", line 13, in <module>FileDataBase("non_existent_file.txt")File "exception_class.py", line 11, in __init__raise_from(DatabaseError('Failed to open'), exc)File "/Users/carawang/Library/Python/2.7/lib/python/site-packages/future/utils/__init__.py", line 483, in raise_fromraise e
__main__.DatabaseError: Failed to open
  • catching exceptions

python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat catch_exceptions.py 
try:raise ValueError('ValueError: dodgy value!')
except ValueError, e:print(e.message)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 catch_exceptions.py 
ValueError: dodgy value!
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 catch_exceptions.py File "catch_exceptions.py", line 3except ValueError, e:^
SyntaxError: invalid syntax
for both:
carawangs-MacBook-Pro:python_compatible carawang$ cat catch_exceptions.py 
try:raise ValueError('ValueError: dodgy value!')
except ValueError as e:print(e.args)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 catch_exceptions.py 
('ValueError: dodgy value!',)
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 catch_exceptions.py 
('ValueError: dodgy value!',)
  • Division

python 2 and python 3 get different results:

carawangs-MacBook-Pro:python_compatible carawang$ cat division.py 
result = [2/3, 3/2]
print(result)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 division.py 
[0, 1]
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 division.py 
[0.6666666666666666, 1.5]

for both:

carawangs-MacBook-Pro:python_compatible carawang$ cat division.py 
from __future__ import division
from past.utils import old_div
result = [2/3, 3/2]
print(result)
result = [old_div(2, 3), old_div(3, 2)]
print(result)
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 division.py 
[0.6666666666666666, 1.5]
[0, 1]
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 division.py 
[0.6666666666666666, 1.5]
[0, 1]
  • Long integers

Python3  取消了short integers而仅支持int。

for python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat integer.py 
k = 123456789999
print(type(k))
lk = 123456789999L
print(type(lk))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 integer.py 
<type 'int'>
<type 'long'>
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 integer.py File "integer.py", line 3lk = 123456789999L^
SyntaxError: invalid syntax

for both:

carawangs-MacBook-Pro:python_compatible carawang$ cat integer.py 
from builtins import int
from past.builtins import long
if isinstance(1234567890, int):print(type(1234567890))
if isinstance(1, (int, long)):print(type(1))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 integer.py 
<type 'int'>
<type 'int'>
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 integer.py 
<class 'int'>
<class 'int'>
 
  • Octal constants

for python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat octal_constant.py 
from decimal import Decimal
print(int(Decimal(0644)))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 octal_constant.py 
420
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 octal_constant.py File "octal_constant.py", line 2print(int(Decimal(0644)))^
SyntaxError: invalid token
for both:
carawangs-MacBook-Pro:python_compatible carawang$ cat octal_constant.py 
from decimal import Decimal
print(int(Decimal(0o644)))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 octal_constant.py 
420
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 octal_constant.py 
420
  • Backtick repr

for python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat repr.py 
hello = "hello"
print(hello)
print(`hello`)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 repr.py 
hello
'hello'
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 repr.py File "repr.py", line 3print(`hello`)^
SyntaxError: invalid syntax
for both:
carawangs-MacBook-Pro:python_compatible carawang$ cat repr.py 
hello = "hello"
print(hello)
print(repr(hello))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 repr.py 
hello
'hello'
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 repr.py 
hello
'hello'
 
  • Unicode String/Byte String/BaseString

我们在此处仅列出兼容的代码

carawangs-MacBook-Pro:python_compatible carawang$ cat string.py 
a_bytestring = b'testing'
a_unicodestring = u'testing'
a_str = 'testing'print(type(a_bytestring))
print(type(a_unicodestring))
print(type(a_str))
# python3 does not support basetring()
#print(isinstance(a_bytestring, basestring))
print(isinstance(a_bytestring, str))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 string.py 
<type 'str'>
<type 'unicode'>
<type 'str'>
True
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 string.py 
<class 'bytes'>
<class 'str'>
<class 'str'>
False
  • Imports relative to a package

假设包结构为:

carawangs-MacBook-Pro:my_pkg carawang$ tree
.
├── __init__.py
├── sub_m1.py
└── sub_m2.py0 directories, 3 files

for both support:

carawangs-MacBook-Pro:my_pkg carawang$ cat sub_m2.py
TEST = True
carawangs-MacBook-Pro:my_pkg carawang$ cat sub_m1.py 
import sub_m2
print(sub_m2.TEST)
carawangs-MacBook-Pro:my_pkg carawang$ python2.7 sub_m1.py 
True
carawangs-MacBook-Pro:my_pkg carawang$ python3.7 sub_m1.py 
True

for both non-support:

carawangs-MacBook-Pro:my_pkg carawang$ cat sub_m1.py 
from . import sub_m2
print(sub_m2.TEST)
carawangs-MacBook-Pro:my_pkg carawang$ cat sub_m2.py 
TEST = True
carawangs-MacBook-Pro:my_pkg carawang$ python2.7 sub_m1.py 
Traceback (most recent call last):File "sub_m1.py", line 1, in <module>from . import sub_m2
ValueError: Attempted relative import in non-package
carawangs-MacBook-Pro:my_pkg carawang$ python3.7 sub_m1.py 
Traceback (most recent call last):File "sub_m1.py", line 1, in <module>from . import sub_m2
ImportError: cannot import name 'sub_m2' from '__main__' (sub_m1.py)
这个地方应该有问题。。。。。
  • Dictionaries

for python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat dict.py 
heights = {'Fred': 175, 'Anne': 166, 'Joe': 192}
for key in heights.iterkeys():print(key)
for value in heights.itervalues():print(value)
for (key, value) in heights.iteritems():print(key, value)
keylist = heights.keys()
valuelist = heights.values()
print(isinstance(keylist, list))
print(keylist)
print(isinstance(valuelist, list))
print(valuelist)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 dict.py 
Anne
Joe
Fred
166
192
175
('Anne', 166)
('Joe', 192)
('Fred', 175)
True
['Anne', 'Joe', 'Fred']
True
[166, 192, 175]
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 dict.py 
Traceback (most recent call last):File "dict.py", line 2, in <module>for key in heights.iterkeys():
AttributeError: 'dict' object has no attribute 'iterkeys'
carawangs-MacBook-Pro:python_compatible carawang$ cat dict_cp.py 
heights = {'Fred': 175, 'Anne': 166, 'Joe': 192}
#for key in heights.iterkeys():
#    print(key)
#for value in heights.itervalues():
#    print(value)
#for (key, value) in heights.iteritems():
#    print(key, value)
keylist = heights.keys()
valuelist = heights.values()
print(isinstance(keylist, list))
print(keylist)
print(isinstance(valuelist, list))
print(valuelist)
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 dict_cp.py
False
dict_keys(['Fred', 'Anne', 'Joe'])
False
dict_values([175, 166, 192])
for both:
carawangs-MacBook-Pro:python_compatible carawang$ cat dict.py 
heights = {'Fred': 175, 'Anne': 166, 'Joe': 192}
for key in heights.keys():print(key)
for value in heights.values():print(value)
for (key, value) in heights.items():print(key, value)
keylist = list(heights)
valuelist = list(heights.values())
print(isinstance(keylist, list))
print(keylist)
print(isinstance(valuelist, list))
print(valuelist)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 dict.py 
Anne
Joe
Fred
166
192
175
('Anne', 166)
('Joe', 192)
('Fred', 175)
True
['Anne', 'Joe', 'Fred']
True
[166, 192, 175]
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 dict
/usr/local/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python: can't open file 'dict': [Errno 2] No such file or directory
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 dict.py 
Fred
Anne
Joe
175
166
192
Fred 175
Anne 166
Joe 192
True
['Fred', 'Anne', 'Joe']
True
[175, 166, 192]
 
  • xrange vs range

for python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat range.py 
for i in xrange(5):print(i)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 range.py 
0
1
2
3
4
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 range.py 
Traceback (most recent call last):File "range.py", line 1, in <module>for i in xrange(5):
NameError: name 'xrange' is not defined

for both:

carawangs-MacBook-Pro:python_compatible carawang$ cat range.py 
for i in range(5):print(i)
range_list = list(range(5))
print(isinstance(range_list, list))
print(range_list)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 range.py 
0
1
2
3
4
True
[0, 1, 2, 3, 4]
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 range.py 
0
1
2
3
4
True
[0, 1, 2, 3, 4]
  • map

for python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat map.py 
def f(x):return int(x)+1
a_list = list(range(5))
b_list = [f(x) for x in a_list]
c_list = map(f, a_list)
print(type(c_list))
print(b_list)
print(c_list)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 map.py 
<type 'list'>
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 map.py 
<class 'map'>
[1, 2, 3, 4, 5]
<map object at 0x106beaac8>

for both:

carawangs-MacBook-Pro:python_compatible carawang$ cat map.py 
def f(x):return int(x)+1
a_list = list(range(5))
b_list = [f(x) for x in a_list]
c_list = list(map(f, a_list))
print(type(c_list))
print(b_list)
print(c_list)
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 map.py 
<type 'list'>
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 map.py 
<class 'list'>
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
  • raw_input & input

for python2 only:

carawangs-MacBook-Pro:python_compatible carawang$ cat input.py 
name = raw_input('What is your name?')
print("hello {}".format(name))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 input.py 
What is your name?cara
hello cara
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 input.py 
Traceback (most recent call last):File "input.py", line 1, in <module>name = raw_input('What is your name?')
NameError: name 'raw_input' is not defined

 

for both:

carawangs-MacBook-Pro:python_compatible carawang$ cat input.py 
from builtins import input
name = input('What is your name?')
print("hello {}".format(name))
carawangs-MacBook-Pro:python_compatible carawang$ python2.7 input.py 
True
What is your name?cara
hello cara
carawangs-MacBook-Pro:python_compatible carawang$ python3.7 input.py 
What is your name?cara
hello cara
  • More

 https://python-future.org/compatible_idioms.html

这篇关于python便利贴:python2-3兼容的代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/622637

相关文章

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地