Type hints最大的好处就是易于代码维护。当新成员加入,想要贡献代码时,能减少很多时间。

也方便我们在调用汉书时提供了错误的类型传递导致运行时错误的检测。

第一个类型注解示例

我们使用一个简单例子,两个整数相加。

def add(a, b):
return a + b

上面的例子,可工作于任意可以进行+操作符的对象。如果我们仅让该函数只能对整型作为参数,然后也只是返回整型结果呢?

def add(a: int, b: int) -> int:
return a + b

我们注意到,返回类型是在函数定义末尾使用 -> 符号来指明。

使用mypi及更多例子

Mypy是为Python构建的静态类型检查器。如果我们使用上面的类型注解,mypy可以在代码中

帮我们找到一些错误。你可以使用在开发流程中任意阶段使用它,比如是在CI中作适当的测试。

安装mypy

我们在虚拟环境中安装mypy

$ pip install mypy

我们的示例

我们会进行如下示例描述,虽然代码作用不大,但是我们可以通过它来学习类型注解以及mypy.

class Student:

    def __init__(self, name, batch, branch, roll):
self.name = name
self.batch = batch
self.branch = branch
self.roll = roll
self.semester = None
self.papers = {} def is_passed(self):
"To find if the student has pass the exam in the current semester"
for k, v in self.papers.items():
if v < 34:
return False return True def total_score(self):
"Returns the total score of the student"
total = 0
for k, v in self.papers.items():
total += v return total std1 = Student("Kushal", 2005, "cse", "123")
std2 = Student("Sayan", 2005, "cse", 121)
std3 = Student("Anwesha", 2005, "law", 122) std1.papers = {"english": 78, "math": 82, "science": 77}
std2.papers = {"english": 80, "math": 92, "science": "78"}
std3.papers = {"english": 82, "math": 87, "science": 77} for std in [std1, std2, std3]:
print("Passed: {0}. The toral score of {1} is {2}".format(std.is_passed(), std.name, std.total_score()))

你可能发现了代码中其实有错误,但是在实际开发过程我们经常会发生,并且除了在运行时发现,我们并没有其他更好的机制。

使用 mypy

我们通过mypy来执行我们的代码,我们把文件取名为students2.py

加入一些类型注解

我们将会在__init__方法中加入一些类型注解。为减少代码长度,修改如下:

class Student:

    def __init__(self, name: str, batch: int, branch: str, roll: int) -> None:
self.name = name
self.batch = batch
self.branch = branch
self.roll = roll
self.semester = None
self.papers = {} $ mypy students2.py
students2.py:9: error: Need type annotation for 'papers'
students2.py:29: error: Argument 4 to "Student" has incompatible type "str"; expected "int"

可以看到mypy有提示哪些变量没有类型注解,还有在29行,参数我们期望的是整型,但在调用时传递了字符串类型,现在让我们来修正他。

from typing import Dict

class Student:

    def __init__(self, name: str, batch: int, branch: str, roll: int) -> None:
self.name = name
self.batch = batch
self.branch = branch
self.roll = roll
self.semester = None
self.papers: Dict[str, int] = {} def is_passed(self):
"To find if the student has pass the exam in the current semester"
for k, v in self.papers.items():
if v < 34:
return False return True def total_score(self):
"Returns the total score of the student"
total = 0
for k, v in self.papers.items():
total += v return total std1: Student = Student("Kushal", 2005, "cse", 123)
std2: Student = Student("Sayan", 2005, "cse", 121)
std3: Student = Student("Anwesha", 2005, "law", 122) std1.papers = {"english": 78, "math": 82, "science": 77}
std2.papers = {"english": 80, "math": 92, "science": 78}
std3.papers = {"english": 82, "math": 87, "science": 77} for std in [std1, std2, std3]:
print("Passed: {0}. The toral score of {1} is {2}".format(std.is_passed(), std.name, std.total_score()))

现在,没有任何错误了。在第一行我们还从typing包引入了Dcit。并作为了self.paper的类型注解,这里的意思就是该变量是字典类型,使用字符串作为键,整型作为值。我们设置std1, std2和std3变量注解为Student类。

现在,我们给papers变量赋一些错误类型的值。

std1.papers = ["English", "Math"]

或者错误的字典键值对

std2.papers = {1: "Engish", 2: "Math"}

我们能看到类似如下错误

$ mypy students2.py
students2.py:35: error: Incompatible types in assignment (expression has type List[str], variable has type Dict[str, int])
students2.py:36: error: Dict entry 0 has incompatible type "int": "str"
students2.py:36: error: Dict entry 1 has incompatible type "int": "str"

更多类型注解示例

from typing import List, Tuple, Sequence, Optional

values: List[int] = []
city: int = 350 # The city code, not a name # This function returns a Tuple of two values, a str and an int
def get_details() -> Tuple[str, int]:
return "Python", 5 # The following is an example of Tuple unpacking
name: str
marks: int
name, marks = get_details() def print_all(values: Sequence) -> None:
for v in values:
print(v) print_all([1,2,3])
print_all({"name": "kushal", "class": 5})
# alltypes.py:23: error: Argument 1 to "print_all" has incompatible type Dict[str, object]; expected Sequence[Any]
# But running the code will give us no error with wrong output def add_ten(number: Optional[int] = None) -> int:
if number:
return number + 10
else:
return 42 print(add_ten())
print(add_ten(12))

你可以从PEP 484了解更多类型。typing模块进行更多例子解释如何在代码中使用类型注解。

最新文章

  1. RabbitMQ之入门
  2. Web的Ajax应用开发模式(三)——Ajax的开发
  3. mysql 启动错误-server PID file could not be found
  4. 永久存储:腌制一缸美味的泡菜 - 零基础入门学习Python031
  5. php实现加好友功能
  6. AngularJS进阶(十五)Cookie &#39;data&#39; possibly not set or overflowed because it was too large
  7. eclipse 的缓存问题
  8. 20个命令行工具监控 Linux 系统性能【转载】
  9. Git 学习笔记--拉取远程分支到本地
  10. [转载] Web Service工作原理及实例
  11. Codeforces 785E. Anton and Permutation
  12. 七、springboot整合Spring-data-jpa
  13. USACO 6.4 Wisconsin Squares
  14. python 四种单例模式
  15. 服务 进程守护 MarsDaemon 简介
  16. New Concept English three(11)
  17. ZOJ 3946 Highway Project(Dijkstra)
  18. OC中的block作方法参数时的用法
  19. Hadoop完全分布式环境下,DataNode进程正常启动,但是网页上不显示DataNode节点
  20. HDU 1248寒冰王座-全然背包或记忆化搜索

热门文章

  1. Linux-MySQL主从配置
  2. QMainFrame类
  3. hdu-5861 Road(并查集)
  4. codeforces 612D The Union of k-Segments (线段排序)
  5. HihoCoder1338 A Game(记忆化搜索)
  6. 多级联动下拉菜单--cxSelect
  7. http头部解释
  8. 51nod 1967 路径定向——欧拉回路
  9. MySQL查询计划输出列的含义
  10. centos7 中文乱码解决方法