Python■你应该知道的Python3.6、3.7、3.8新特性( 三 )


在 Python 3.5 中 , 注解的语法获得标准化 , 此后 , Python 社区广泛使用了注解类型提示 。
但是 , 注解仅仅是一种开发工具 , 可以使用 PyCharm 等 IDE 或 Mypy 等第三方工具进行检查 , 并不是语法层面的限制 。
我们前面的猜数程序如果添加类型注解 , 它应该是这样的:
\"\"\"猜数字游戏\"\"\"def guess(target:str):
   user_guess:str = input(\"请输入你猜的数 >>> \")
   breakpoint()    if user_guess == target:        return \"你猜对了!\"
   else:        return \"猜错了\"if __name__ == '__main__':
   a:int = 100
   print(guess(a))

PyCharm会给我们灰色的规范错误提醒 , 但不会给红色的语法错误提示 。
用注解作为类型提示时 , 有两个主要问题:启动性能和前向引用 。

  • 在定义时计算大量任意表达式相当影响启动性能 , 而且 typing 模块非常慢
  • 你不能用尚未声明的类型来注解
typing 模块如此缓慢的部分原因是 , 最初的设计目标是在不修改核心 CPython 解释器的情况下实现 typing 模块 。 随着类型提示变得越来越流行 , 这一限制已经被移除 , 这意味着现在有了对 typing 的核心支持 。
而对于向前引用 , 看下面的例子:
class User:
   def __init__(self name: str prev_user: User) -> None:
       pass

错误在于 User类型还没有被声明 , 此时的 prev_user 不能定义为 User 类型 。
为了解决这个问题 , Python3.7 将注解的评估进行了推迟 。 并且 , 这项改动向后不兼容 , 需要先导入annotations , 只有到Python 4.0后才会成为默认行为 。
from __future__ import annotationsclass User:
   def __init__(self name: str prev_user: User) -> None:
       pass

或者如下面的例子:
class C:
   def validate_b(self obj: B) -> bool:
       ...class B:
   ...

3、新增dataclasses模块这个特性可能是 Python3.7以后比较常用的 , 它有什么作用呢?
假如我们需要编写一个下面的类:
from datetime import datetimeimport dateutilclass Article(object):
   def __init__(self _id author_id title text tags=None
                created=datetime.now() edited=datetime.now()):
   self._id = _id
   self.author_id = author_id
   self.title = title
   self.text = text
   self.tags = list() if tags is None else tags
   self.created = created
   self.edited = edited    if type(self.created) is str:
      self.created = dateutil.parser.parse(self.created)    if type(self.edited) is str:
      self.edited = dateutil.parser.parse(self.edited)    def __eq__(self other):
       if not isinstance(other self.__class__):            return NotImplemented
       return (self._id self.author_id) == (other._id other.author_id)    def __lt__(self other):