前言
完残!😂,最近看之前写的 Python 代码老得琢磨这比变量的类型是啥(Python 无类型系统xxx),不愧是我写的!
看段之前写的实现迭代器模式的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
   |  class Iterator(object):     def hasNext():         pass
      def next():         pass
 
  class Aggregate(object):     def iterator():         pass
  class BookShelf(Aggregate):     def __init__(self):         self._books = []         self._last = 0
      def getBookAt(self, index):         return self._books[index]
      def appendBook(self, book):         self._books.append(book)         self._last = self._last + 1
      def getLength(self):         return self._last
      def iterator(self):         return BookShelfIterator(self)
  class BookShelfIterator(Iterator):     def __init__(self, bookShelf):         self._bookShelf = bookShelf         self._index = 0
      def hasNext(self):         if self._index < self._bookShelf.getLength():             return True         else:             return False
      def next(self):         book = self._bookShelf.getBookAt(self._index)         self._index = self._index + 1         return book
  class Book():     def __init__(self, name):         self._name = name
      def getName(self):         return self._name
  if __name__ == "__main__":     bookShelf = BookShelf()     bookShelf.appendBook(Book("A"))     bookShelf.appendBook(Book("B"))     bookShelf.appendBook(Book("C"))     bookShelf.appendBook(Book("D"))
      it = bookShelf.iterator()     while it.hasNext():         book = it.next()         print(book.getName())
 
  | 
 
有一丢丢难读(不通读的话,会乱猜某变量类型),回想之前在 PyCon China 2019 的大会资聊曾看到过类型检查相关的演讲主题,回顾下演讲视频。水一波,写篇文章了解下 Python 标准(PEP 3107 & PEP 484 )支持的 mypy。
类型系统:编译期的类型推导检查规则,类型系统属于一种轻量级的形式化方法(一种数学方法)
使用-mypy
1 2 3 4
   | # 安装 mypy pip install mypy # 使用 mypy 做类型检查 mypy module_name.py
   | 
 
以下使用方式适用于 Python 3.6 及以上的版本。值得注意:mypy 默认的推导类型不可为 None
变量的类型注释
1 2 3 4 5 6 7 8
   | integer: int = 1 string: str = "ShanSan" err_str: str = 1   child: bool = True
  none: int - None  
  print(integer, string)
   | 
 
内建类型
关于更多 mypy 的类型系统内建的类型可参考:https://mypy.readthedocs.io/en/stable/builtin_types.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | from typing import Dict, Tuple, Optional, Iterable, Union
  x: Dict[str, float] = {'field': 2.0}
 
  x: Tuple[int, str, float] = (3, "yes", 7.5)
 
  y: Tuple[int, str, float] = (3, "yes", 7.5, 11)
  op: Optional[str] = None  
 
  l: Iterable = [1] t: Iterable = (1, 2) d: Iterable = {1: 1}
 
  str_int1: Union[str, int] = 1 str_int2: Union[str, int] = "ss" str_int3: Union[str, int] = None  
   | 
 
函数注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | from typing import NoReturn
  def f1() -> None:     pass
  def f2() -> NoReturn:       pass
  def plus(num1: int, num2: int) -> int:     return num1 + num2
 
  def plus_default(num1: int, num2: int = 3) -> int:     return num1 + num2
 
  def container_param(names: List[str]) -> None:     for name in names:         print(name)
   | 
 
类成员注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | class MyClass:     attr: int          charge_percent: int = 100
           def __init__(self) -> None:         pass
           def my_method(self, num: int, str1: str) -> str:         return num * str1
 
  x: MyClass = MyClass()
   | 
 
结尾
OK, 差不多了,对之前的迭代器模式的代码改造一波
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
   | from typing import List, Iterable
 
  class Iterator(object):     def hasNext(self):         pass
      def next(self):         pass
 
  class Aggregate(object):     def iterator(self):         pass
  class BookShelf(Aggregate):     def __init__(self) -> None:         self._books: List[Book] = []         self._last: int = 0
      def getBookAt(self, index: int) -> Book:         return self._books[index]
      def appendBook(self, book: Book) -> None:         self._books.append(book)         self._last = self._last + 1
      def getLength(self) -> int:         return self._last
      def iterator(self) -> BookShelfIterator:         return BookShelfIterator(self)
  class BookShelfIterator(Iterator):     def __init__(self, bookShelf) -> None:         self._bookShelf: BookShelf = bookShelf         self._index: int = 0
      def hasNext(self) -> bool:         if self._index < self._bookShelf.getLength():             return True         else:             return False
      def next(self) -> Book:         book: Book = self._bookShelf.getBookAt(self._index)         self._index = self._index + 1         return book
  class Book():     def __init__(self, name) -> None:         self._name: str = name
      def getName(self) -> str:         return self._name
  if __name__ == "__main__":     bookShelf: BookShelf = BookShelf()     bookShelf.appendBook(Book("A"))     bookShelf.appendBook(Book("B"))     bookShelf.appendBook(Book("C"))     bookShelf.appendBook(Book("D"))
      it: Iterator = bookShelf.iterator()     while it.hasNext():         book: Book = it.next()         print(book.getName())
   | 
 
emmm, 舒服了一丢丢/(ㄒoㄒ)/~~
参考