最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 这可能是最全的Python2和Python3的区别及兼容技巧了

    正文概述    2020-08-07   238

    这可能是最全的Python2和Python3的区别及兼容技巧了

    Python 2 or 3 ?

    Python 3 被钦定为 Python 的未来,于 2008 年末发布,是目前正在开发的版本。旨在解决和修正 Python 2 遗留的设计缺陷、清理代码库冗余、追求有且仅有一种最佳实践方式来执行任务等问题。

    起初,由于 Python 3 不能向后兼容的事实,导致了用户采用缓慢,对初学者不友好等问题。但在 Python 社区的努力和决绝态度下,截至龟爷发出邮件之前,已经有了 21903 个 Packages 可以支持 Python 3.5,其中包括了绝大多数最受欢迎的封装库,与此同时也有越来越多的封装库(e.g. Django、Numpy)表示其新版本将不再支持 Python 2。

    Python 2.7 于 3.0 之后的 2010 年 7 月 3 日发布,计划作为 2.x 的最后一个版本。Python 2.7 的历史任务在于通过提供 2 和 3 之间的兼容性措施,使 Python 2.x 的用户更容易将代码移植到 Python 3.x 上。那么如果你希望自己的代码能够兼容两个不同的版本,首先你起码要让代码能够正常的运行在 Python 2.7 上。

    注:下文使用 P2 表示 Python 2.7;使用 P3 表示 Python 3.x。

    不同与兼容

    __future__ 模块是我们首先需要了解的,该模块最主要的作用是支持在 P2 中导入那些在 P3 才生效的模块和函数。是一个非常优秀的兼容性工具库,在下文中给出的许多 兼容技巧 实例都依赖于它。

    特性 在此版本可选 在此版本内置 效果

    nested_scopes	2.1.0b1	2.2	PEP 227:静态嵌套作用域
    generators	2.2.0a1	2.3	PEP 255:简单生成器
    division	2.2.0a2	3.0	PEP 238:除法操作符改动
    absolute_import	2.5.0a1	3.0	PEP 328:Imports 多行导入与绝对相对路径
    with_statement	2.5.0a1	2.6	PEP 343:with 语句
    print_function	2.6.0a2	3.0	PEP 3105:print 语句升级为函数
    unicode_literals	2.6.0a2	3.0	PEP 3112:Bytes 类型

    (__future__ 功能列表)

    统一不等于语法

    P2 支持使用 <> 和 != 表示不等于。

    P3 仅支持使用 != 表示不等于。

    兼容技巧:

    统一使用 != 语法

    统一整数类型

    P2 中整数类型可以细分为短整型 int 和长整型 long。

    P3 废除了短整型,并统一使用 int 表示长整型(不再有 L 跟在 repr 后面)。

    兼容技巧:

    # Python 2 only
    k = 9223372036854775808L
    # Python 2 and 3:
    k = 9223372036854775808
    # Python 2 only
    bigint = 1L
    # Python 2 and 3
    from future.builtins import int
    bigint = int(1)

    统一整数除法

    P2 的除法 / 符号实际上具有两个功能:

    当两个操作数均为整型对象时,进行的是地板除(截除小数部分),返回整型对象;

    当两个操作数存在至少一个浮点型对象时,进行的是真除(保留小数部分),返回浮点型对象。

    P3 的除法 / 符号仅仅具有真除的功能,而地板除的功能则交由 // 来完成。

    兼容技巧:

    # Python 2 only:
    assert 2 / 3 == 0
    # Python 2 and 3:
    assert 2 // 3 == 0
    “True division” (float division):
    # Python 3 only:
    assert 3 / 2 == 1.5
    # Python 2 and 3:
    from __future__ import division    # (at top of module)

    统一缩进语法

    P2 可以混合使用 tab 和 space 两种方式来进行缩进(1 个 tab == 8 个 space),但实际上这一特性并非所有 IDE 都能够支持,会因此出现同样的代码无法跨 IDE 运行的情况。

    P3 统一使用 tab 作为缩进,如果 tab 和 space 同时存在,就会触发异常:

    TabError: inconsistent use of tabs and spaces in indentation.

    兼容技巧:

    统一使用 tab 作为缩进。

    统一类定义

    P2 同时支持新式类(object)和老式类。

    P3 则统一使用新式类,并且只有使用新式类才能应用多重继承。

    兼容技巧:

    统一使用新式类。

    统一字符编码类型

    P2 默认使用 ASCII 字符编码,但因为 ASCII 只支持数百个字符,并不能灵活的满足非英文字符,所以 P2 同时也支持 Unicode 这种更强大的字符编码。不过,由于 P2 同时支持两套字符编码,就难免多出了一些标识和转换的麻烦。

    而 P3 统一使用 Unicode 字符编码,这节省了开发者的时间,同时也可以轻松地在程序中输入和显示更多种类的字符。

    兼容技巧:

    在所有的字符串赋值中均使用前缀 u,或引入 unicode_literals 字符模块。

    # Python 2 only
    s1 = 'PythonTab'
    s2 = u'Python中文网'
    # Python 2 and 3
    s1 = u'PythonTab'
    s2 = u'Python中文网'
    # Python 2 and 3
    from __future__ import unicode_literals    # at top of module
    s1 = 'PythonTab'
    s2 = 'Python中文网'

    统一导入模块的路径搜索方式

    P2 导入一个模块时首先会搜索当前目录(cwd),若非,则搜索环境变量路径(sys.path)。这一特性时常给开发者带来困扰,相信大家都曾经碰到过,尤其当自定义模块与系统模块重名的时候;

    为了解决这个问题,默认的 P3 仅会搜索环境变量路径,当你需要搜索自定义模块时,你可以在包管理模式下将项目路径加入到环境变量中,然后再使用绝对路径和相对路径(以 . 开头)的方式来导入。

    兼容技巧:

    统一使用绝对路径进行自定义模块导入。

    修正列表推导式的变量作用域泄露

    P2 的列表推倒式中的变量会泄露到全局作用域,例如:

    import platform
    print('Python', platform.python_version())
    i = 1
    print('before: I = %s' % i)
    print('comprehension: %s' % [i for i in range(5)])
    print('after: I = %s' % i)
    # OUT
    Python 2.7.6
    before: i = 1
    comprehension: [0, 1, 2, 3, 4]
    after: i = 4

    P3 则解决了这个问题,列表推倒式中的变量不再泄露到全局作用域。

    修正非法比较操作异常

    P2 能够对两个数据类型并不相同的对象进行比较。

    import platform
    print('Python', platform.python_version())
    print("[1, 2] > 'foo' = ", [1, 2] > 'foo')
    print("(1, 2) > 'foo' = ", (1, 2) > 'foo')
    print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2))

    输出

    Python 2.7.6
    [1, 2] > 'foo' = False
    (1, 2) > 'foo' = True
    [1, 2] > (1, 2) = False

    不过,这种看似方便的特性,实际上却是一个定时炸弹,因为你无法唯一的确定到底是什么原因导致的返回值为 False(可能是数据比较、也可能是数据类型不一致)。

    P3 则对其进行了修正,如果比较操作数类型不一致时,会触发 TypeError 异常。

    兼容技巧:

    永远不要比较数据类型不一致的对象。

    统一抛出异常语法

    P2 同时支持新旧两种异常触发语法:

    raise IOError, "file error"   # Old
    raise IOError("file error")   # New

    兼容技巧

    ### 抛出异常
    # Python 2 only:
    raise ValueError, "dodgy value"
    # Python 2 and 3:
    raise ValueError("dodgy value")
    ### 使用 traceback 抛出异常
    # Python 2 only:
    traceback = sys.exc_info()[2]
    raise ValueError, "dodgy value", traceback
    # Python 3 only:
    raise ValueError("dodgy value").with_traceback()
    # Python 2 and 3: option 1
    from six import reraise as raise_
    # or # from future.utils import raise_
    traceback = sys.exc_info()[2]
    raise_(ValueError, "dodgy value", traceback)
    # Python 2 and 3: option 2
    from future.utils import raise_with_traceback
    raise_with_traceback(ValueError("dodgy value"))
    ### 异常链处理
    # Setup:
    class DatabaseError(Exception):
        pass
    # Python 3 only
    class FileDatabase:
        def __init__(self, filename):
            try:
                self.file = open(filename)
            except IOError as exc:
                raise DatabaseError('failed to open') from exc
    # Python 2 and 3:
    from future.utils import raise_from
    class FileDatabase:
        def __init__(self, filename):
            try:
                self.file = open(filename)
            except IOError as exc:
                raise_from(DatabaseError('failed to open'), exc)

    P2 实现异常处理也能够支持两种语法。

    try:
        let_us_cause_a_NameError
    except NameError, err:
    # except NameError as err:
        print err, '--> our error message'

    P3 的异常处理则强制要求使用 as 关键字的方式。

    try:
        let_us_cause_a_NameError
    except NameError as err:
        print(err, '--> our error message')

    统一文件操作函数

    P2 支持使用 file 和 open 两个函数来进行文件操作。

    P3 则统一使用 open 来进行文件操作。

    兼容技巧:

    统一使用 open 函数。

    # Python 2 only:
    f = file(pathname)
    # Python 2 and 3:
    f = open(pathname)

    统一列表迭代器生成函数

    P2 支持使用 range 和 xrange 两个函数来生成可迭代对象,区别在于前者返回的是一个列表类型对象,后者返回的是一个类似生成器(惰性求值)的迭代对象,支持无限迭代。所以当你需要生成一个很大的序列时,推荐使用 xrange,因为它不会一上来就索取序列所需的所有内存空间。如果只对序列进行读操作的话,xrange 方法效率显然会更高,但是如果要修改序列的元素,或者往序列增删元素的话,那只能通过 range 方法生成一个 list 对象了。


    起源地下载网 » 这可能是最全的Python2和Python3的区别及兼容技巧了

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元