准备好从Python2.x转换到3.x了吗

准备好从Python2.x转换到3.x了吗,python,python-3.x,upgrade,python-2.x,Python,Python 3.x,Upgrade,Python 2.x,正如我们现在所知道的(我希望),Python3正慢慢开始取代Python2.x。当然,大多数现有代码最终被移植还需要很多年的时间,但是我们现在可以在2.x版代码中做一些事情来简化切换 显然,看看3.x版本会很有帮助,但是我们现在可以做些什么来让即将到来的转换更加轻松(以及在需要时更容易将更新输出到并发版本)?我特别考虑的是我们可以在脚本开始时使用的行,这些行将使Python的早期版本更类似于3.x,尽管也欢迎使用其他习惯 我能想到的添加到脚本顶部的最明显的代码是: from __future__

正如我们现在所知道的(我希望),Python3正慢慢开始取代Python2.x。当然,大多数现有代码最终被移植还需要很多年的时间,但是我们现在可以在2.x版代码中做一些事情来简化切换

显然,看看3.x版本会很有帮助,但是我们现在可以做些什么来让即将到来的转换更加轻松(以及在需要时更容易将更新输出到并发版本)?我特别考虑的是我们可以在脚本开始时使用的行,这些行将使Python的早期版本更类似于3.x,尽管也欢迎使用其他习惯

我能想到的添加到脚本顶部的最明显的代码是:

from __future__ import division
from __future__ import print_function
try:
    range = xrange
except NameError:
    pass
我能想到的最明显的习惯是
“{0}{1}!”格式(“Hello”,“World”)
用于字符串格式设置


还有其他行和好习惯吗?

每当我真正想要整数除法(而不是浮点数)时,我都会尝试使用
var1//var2
。对于Python3来说,这不是一个很大的进步,但至少我不必回头检查我的所有部分:)

微级别更改和2to3无法充分解决的最大问题是将默认字符串类型从字节更改为Unicode

如果您的代码需要对编码和字节I/O执行任何操作,则需要大量的手动工作来正确转换,以便必须是字节的内容保留为字节,并在正确的阶段进行适当的解码。您会发现一些字符串方法(特别是
format()
)和库调用需要Unicode字符串,因此您可能需要额外的解码/编码周期才能将字符串用作Unicode,即使它们实际上只是字节

有些Python标准库模块在没有适当注意字节/unicode/编码问题的情况下使用2to3进行了粗略的转换,因此它们本身在字符串类型的正确性方面会犯错误,这一事实无助于实现这一点。其中一些问题正在被解决,但至少从Python 3.0到3.2,您将面临来自需要了解字节编码的urllib、email和wsgiref等包的混乱和潜在的错误行为

您可以通过每次编写字符串文字时都要小心来改善问题。使用
u'
字符串表示任何本质上基于字符的内容,
b'
字符串表示任何真正基于字节的内容,
'
字符串表示“默认字符串”类型,如果它不重要或您需要匹配库调用的字符串使用要求

不幸的是,
b'
语法只在Python 2.6中引入,因此这样做会切断早期版本的用户

预计到达时间:

有什么区别

哦,天哪。嗯

一个字节包含一个范围在0到255之间的值,并且可能代表一个二进制数据(例如图像的内容)或一些文本的负载,在这种情况下,必须为如何将一组字符映射到这些字节选择一个标准。大多数“编码”标准都以相同的方式将普通的“ASCII”字符集映射到字节0–127,因此在Python 2中使用字节字符串进行仅ASCII的文本处理通常是安全的

如果您想在字节字符串中使用ASCII集之外的任何字符,您就有麻烦了,因为每个编码都将不同的字符集映射到剩余的字节值128–255,而大多数编码无法将每个可能的字符映射到字节。这就是所有这些问题的根源,当您将文件从一个区域加载到另一个区域的Windows应用程序中时,所有重音或非拉丁字母都会变为错误的字母,造成无法读取的混乱。(又名“mojibake”。)

还有“多字节”编码,通过使用多个字节存储每个字符,尝试将更多字符放入可用空间。这些汉字是为东亚地区引入的,因为那里有很多汉字。但也有UTF-8,一种设计更好的现代多字节编码,可以容纳每个字符

如果您正在使用多字节编码处理字节字符串,而今天您可能会这样做,因为UTF-8的使用非常广泛;实际上,在现代应用程序中不应该使用其他编码,那么,除了跟踪正在使用的编码之外,您还会遇到更多的问题
len()
将告诉您以字节为单位的长度,而不是以字符为单位的长度,如果您开始索引和更改字节,很可能会将多字节序列一分为二,生成无效序列,并且通常会混淆所有内容

因此,Python1.6及更高版本具有本机Unicode字符串(拼写为
u'something'
),其中字符串中的每个单元都是字符,而不是字节。您可以
len()
对它们进行切片、替换、正则化,它们的行为将始终正常。对于文本处理任务,它们无疑更好,这就是为什么Python3将它们作为默认字符串类型(而不必在
'
前面加
u

问题在于,许多现有接口(如Windows以外的操作系统上的文件名、HTTP或SMTP)主要是基于字节的,并有单独的编码方式。因此,当您处理需要字节的组件时,必须注意将unicode字符串正确编码为字节,在Python3中,您必须在一些以前不需要的地方显式地进行编码

Unicode字符串在内部每个单元占用“两个字节”的存储空间是一个内部实现细节。你永远也看不到那个储藏室;你不应该用字节来考虑它。无论Python选择如何在内存中表示,您正在处理的单元在概念上都是字符

。。。