准备好从Python 2.x转换为3.x.

Way*_*ner 11 python upgrade python-2.x python-3.x

我们现在都知道(我希望),Python 3正在慢慢开始取代Python 2.x. 当然,在大多数现有代码最终被移植之前将会有很多年,但是我们现在可以在2.x版本的代码中做些事情来简化切换.

显然,看看3.x中的新功能会有所帮助,但是我们现在可以做些什么来使即将进行的转换更加轻松(如果需要,还可以更容易地将更新输出到并发版本)?我特别考虑的是我们可以启动脚本的行,这将使早期版本的Python更像3.x,尽管其他习惯也是受欢迎的.

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

from __future__ import division
from __future__ import print_function
try:
    range = xrange
except NameError:
    pass
Run Code Online (Sandbox Code Playgroud)

我能想到的最明显的习惯是 "{0} {1}!".format("Hello", "World") 字符串格式化.

还有其他任何线条和良好的习惯吗?

bob*_*nce 12

不能由微电平的变化和2to3的适当处理的最大问题是默认的字串类型的从字节到Unicode的变化.

如果你的代码需要对编码和字节I/O做任何事情,那么需要大量的手动工作才能正确转换,因此必须是字节的东西仍然是字节,并在正确的阶段进行适当的解码.你会发现,一些字符串的方法(尤其是format())和库调用需要Unicode字符串,所以你可能需要额外的解码/编码周期只是为了即使他们真的只是用字节字符串为Unicode.

一些Python标准库模块使用2to3粗略地转换而没有适当注意字节/ unicode /编码问题这一事实并没有帮助,因此他们自己犯了什么字符串类型是合适的错误.其中一部分正在被淘汰,但至少从Python 3.0到3.2,您将面临来自urllib,email和wsgiref等需要了解字节编码的软件包的混乱和潜在的错误行为.

每次编写字符串文字时都要小心,以改善问题.将u''字符串用于任何本质上基于字符的b''字符串,将字符串用于任何真正的字节,以及''用于"默认字符串"类型的字符串无关紧要或者您需要匹配库调用的字符串使用要求.

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

ETA:

有什么不同?

天啊.好...

一个字节包含0-255范围内的值,并且可以表示二进制数据的加载(例如图像的内容)或一些文本,在这种情况下,必须有一个标准被选择用于如何映射一组字符到那些字节.大多数这些"编码"标准以相同的方式将普通的"ASCII"字符集映射到字节0-127中,因此在Python 2中使用字节字符串进行纯ASCII文本处理通常是安全的.

如果你想在字节字符串中使用ASCII集之外的任何字符,你就会遇到麻烦,因为每个编码都将一组不同的字符映射到剩余的字节值128-255,并且大多数编码都不能映射每个字符可能的字符到字节.这是所有这些问题的根源,在这些问题中,您将文件从一个区域设置加载到另一个区域设置的Windows应用程序中,并且所有重音或非拉丁字母都变为错误的字母,从而造成难以理解的混乱.(又名'mojibake'.)

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

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

出于这个原因,Python 1.6及更高版本具有本机Unicode字符串(拼写u'something'),其中字符串中的每个单元都是字符,而不是字节.你可以len(),切片,替换它们,正则表达式,它们总是表现得恰到好处.对于文本处理任务,它们无疑是更好的,这就是为什么Python 3使它们成为默认字符串类型(无需在u之前放置'').

问题在于,许多现有接口(例如Windows以外的操作系统,HTTP或SMTP上的文件名)主要基于字节,并使用单独的方式指定编码.因此,当您处理需要字节的组件时,您必须注意将unicode字符串正确编码为字节,而在Python 3中,您必须在不需要之前的某些地方明确地执行此操作.

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

...在旁边:

这不是真的.在像Windows构建的Python的"窄版本"中,Unicode字符串的每个单元在技术上不是字符,而是UTF-16'代码单元'.对于基本多语言平面中的字符,从0x0000-0xFFFF你不会注意到任何差异,但如果你使用的是16位范围以外的字符,那些在"星界"中的字符,你会发现它们是两个单位而不是一个单位,再次,当你切割它们时,你可能会分裂一个字符.

这是非常糟糕的,因为在Unicode增长超过65,000个字符限制之前,Windows(以及其他人,如Java)在UTF-16上作为内存存储机制确定了.但是,使用这些扩展字符的情况仍然非常少见,Windows上的任何人都会习惯在许多应用程序中使用它们,因此对您来说可能并不重要.

在"宽版本"中,Unicode字符串由真实字符"代码点"单元组成,因此即使是BMP之外的扩展字符也可以一致且容易地处理.要付出的代价是效率:每个字符串单元占用内存中的四个字节的存储空间.


eld*_*his 5

我试图养成使用像var1//var2我实际想要整数除法(而不是浮点数)的东西的习惯.迈向Python 3并没有迈出一大步,但至少我不必回去检查我所有的部门:)