从Python2到Python3

发布于 2017-08-22 10:33:51

Py3新的语法特性

  • PEP 498, 格式化字符串字面量
  • PEP 515, 数字字面量中的下划线
  • PEP 526, 变量注解中的语法
  • PEP 525, 异步生成器
  • PEP 520, 异步解析式

Python2 和 Python3 语法上一些区别

这部分主要摘抄自知乎,董伟明的总结不错,不过我这种分类更清晰 :)

  1. 新增语法
    • 新增了关键字 nonlcoal,使得非局部变量成为可能
    • 异步IO async/await
    • 格式化字符串变量
    • 类型标注
    • yield fromyield for关键词
    • 添加__annotations____context____traceback____qualname__等dunder方法。
  2. 删除的语法
    • 去掉了 <> cmp等。。
  3. 功能变更
    1. 删除了unicode对象,str默认为unicode字符串;bytes代替了原来的str(字节序列)
      1. 不再需要在文件顶部注明# coding: utf-8
      2. Py2恼人的编码问题?
    2. 语句变成函数
      • print
      • exec
    3. 整数除法的结果不再强制是整数(Py2可通过from __future__ import division来兼容Py3)
    4. 返回列表的很多函数都变成了返回迭代器
      1. range替代Py2的xrange,即range默认返回迭代器,而不是list
      2. 字典对象的 dict.keys()、dict.values() 方法都不再返回列表,而是以一个类似迭代器的 “view” 对象返回。
      3. 高阶函数 map、filter、zip 返回的也都不是列表对象了。
      4. Python2的迭代器必须实现 next 方法;而 Python3 改成了 __next__,迭代器没有next()函数
    5. 库结构有了变化,但功能没变?
    6. python3 彻底废弃了 long+int 双整数实现的方法,统一为 int,支持高精度整数运算
    7. 八进制数必须写成0o777,原来的形式0777不能用了
    8. Py3没有旧式类,不用像class Foo(object): pass显式地子类化object
    9. Py3的input函数总是返回字符串,Py2则需要用raw_input
    10. 异常处理
      • 在2.x时代,所有类型的对象都是可以被直接抛出的
      • 在3.x时代,只有继承自BaseException的对象才可以被抛出
    11. 其中的某些变更也可以在这里看出。注意这些转换可能是转换为更“标准”的写法。
  4. BUG修复
  5. 优化:重新实现了dict可以减少20%-25%的内存使用;提升pickle序列化和反序列化的效率;collections.OrderedDict改用C实现;通过os.scandir对glob模块中的glob()及iglob()进行优化,使得它们现在大概快了3-6倍等

概念回顾

Python2新式类和经典类的区别

  1. 写法不一样(略)
  2. 在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索。
  3. 新式类更符合OOP编程思想,统一了python中的类型机制。
  4. 新式类的其他属性
    • Py3 类实例的__class__type(instance)一致
      # Python2.7
      >>> class A:pass
      ...
      >>> a = A()
      >>> a.__class__
      <class __main__.A at 0x02C17538>
      >>> type(a)
      <type 'instance'>
      
    • __slots__
    • __getattribute__

迭代器(Iterator)与生成器(Generator)的区别

迭代器是一个更抽象的概念,任何对象,如果它的类有next方法(Py3是__next__)和__iter__方法返回自己本身。

每个生成器都是一个迭代器,但是反过来不行。通常生成器是通过调用一个或多个yield表达式构成的函数生成的。同时满足迭代器的定义。

  • 生成器表达式:(i*i for i in xrange(start, stop))
  • 列表推倒式:[i*i for i in xrange(start, stop)]

两者的相同点:对象迭代完后就不能重新迭代了

PEP 3107 – Function Annotations

讲了Python类型注解的基础(原则)、语法,如何在代码里获取这些注解,以及标准库所要做的跟进(pydoc、inspec)

PEP 328 – Imports: Multi-Line and Absolute/Relative

相对导入问题

26.7. 2to3 - Automated Python 2 to 3 code translation — Python 3.6.2

Python2迁移Python3问题

PEP 484 – Type Hints

  • Py3的类型提示很大部分参考了mypy
  • 注解类型都需要从Python模块typing导入。
  • 常见的类型
    • 基础类型
      • Any
      • Union[t1, t2, …]
      • Optional[t1]
      • Tuple[t1, t2, …, tn]
      • Callable[[t1, t2, …, tn], tr]
      • 可能添加:Intersection[t1, t2, …]
    • 泛型(Generic Type)
      • “Classes, that behave as generic type constructors are called generic types.”
      • 泛型函数
      • 类型变量
      • Iterable
      • 预定义的泛型
        • collections.abc里所有的东西
        • Dict、List、Set、FrozenSet等
        • re.Pattern[AnyStr], re.Match[AnyStr]
        • io.IO[AnyStr], io.TextIO ~ io.IO[str], io.BinaryIO ~ io.IO[bytes].
    • 自定义类型
      • TypeVar
      • Generic
  • 类型注释(Type Comments)
  • typing模块

The type system supports unions, generic types, and a special type named Any which is consistent with (i.e. assignable to and from) all types. This latter feature is taken from the idea of gradual typing. Gradual typing and the full type system are explained in PEP 483.

Py的类型系统支持联合类型,泛型,和一个被命名为Any的特殊类型,这个类型代表了所有的类型。

PEP 483 – The Theory of Type Hints

其他参考:

其他链接

comments powered by Disqus