Python中使用Type hinting 和 annotations
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模块进行更多例子解释如何在代码中使用类型注解。
Python中使用Type hinting 和 annotations的更多相关文章
- Python 中的type和object详解
		
1.python中的类 Python2.x 中的类分为两种,一种是所有继承自object的新式类,另外一种是经典类classobj, 新式类的写法: class A(object): pass 经典类 ...
 - python中的type和object详解
		
关于这篇博客 这篇博客主要描述Python的新风格对象(new-style objects),如下: <type 'type'>和<type 'object'>分别是什么? 用 ...
 - Python中使用type、metaclass动态创建方法和属性
		
1: type() 我们知道动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Person的class: class Person(obj ...
 - python中的type
		
我们常用type()来查看类型,使用方法如下: 1 a = "zzzq" 2 b = 1 3 c = (1, "zzq123") 4 d = [2, " ...
 - python 中的type
		
1. type(object) -> the object's type 返回的是object的类型,即对象的类定义 例如:用元类动态生成子类metaclass = type(father) ...
 - Python中的type(),isinstance,()dir(),的区别
		
1.type() type(),获取一个变量的类型,返回值为:<class '类名'>,属于class类型2.isinstance() isinstance(),判断一个对象是否属于某种数 ...
 - [py]python中的特殊类class type和类的两面性图解
		
生活中的模具 生活中 编程 万物都从无到有, 起于烟尘 () 生产原料,铁 object 车床-生产各类模具 元类即metaclass,对应python的class type 模具-生产各类实在的物品 ...
 - Python中type()详解:动态创建类
		
众所周知: type()函数可以查看变量的类型: 先看一个简单的列子来看一下type查看变量类型 class Animal(): pass a=Animal() print(type(a)) prin ...
 - Python中请使用isinstance()判断变量类型
		
一.isinstance() 在Python中可以使用type()与isinstance()这两个函数判断对象类型,而isinstance()函数的使用上比type更加方便. # coding=utf ...
 
随机推荐
- 数学建模--matlab基础知识
			
虽然python也能做数据分析,不过参加数学建模,咱还是用专业的 1. Matlab-入门篇:Hello world! 程序员入门第一式: disp(‘hello world!’) 2. 基本运算 先 ...
 - Python 标准库 —— 邮件(email)与邮件服务器(smtplib)
			
你真的懂邮件吗?邮件包括如下四部分内容: 发送人:from_addr 接收人:to_addr 主题:subject 正文:msg(mime text 格式文本) 其中发送者,接收者,又需要两部分的内容 ...
 - loj515贪心只能过样例
			
bitset练习题... 位运算真的是玄学... 一开始真的“只能过样例” 后来发现把左移写成了小于号 鬼知道我在想什么/手动微笑 loj第一题 #include<iostream> #i ...
 - uoj problem 10
			
uoj problem 10 题目大意: 给定任务若干,每个任务在\(t_i\)收到,需要\(s_i\)秒去完成,优先级为\(p_i\) 你采用如下策略: 每一秒开始时,先收到所有在该秒出现的任务,然 ...
 - 【Python】正则表达式中使用变量
			
我们有时想把变量放进正则表达式中来匹配想要的结果.Python中使用 re.compile(r''+变量+''),其中正则表达式中的“变量”应为字符串形式. import re regex_test_ ...
 - VBA中的函数Timer用法
			
第1.40例 Timer 函数一.题目: 要求编写一段代码,运用 Timer 函数来计算本代码运行所化的时间.二.代码:Sub 示例_1_040() Dim t, i&, a t ...
 - 杂项-权限管理:Spring Secutity
			
ylbtech-杂项-权限管理:Spring Secutity Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在S ...
 - seaweedfs安装配置使用
			
Saeweedfs是一个由golang语言开发的分布式对象存储系统,很适合做图片服务器,性能很好,安装操作都很简单,并且可兼容挂载提供路径访问的方式,可以较为便捷的将nginx+nfs此类的文件服务器 ...
 - django examples 学习笔记(1)创建一个独立的python环境
			
pip install virtualenv 创建一个虚拟环境 virtualenv my_env 创建一个独立的环境 source my_env/bin/activate 激活 ...
 - python 字典 get 小例子
			
语法 get()方法语法: dict.get(key, default=None) 参数 key -- 字典中要查找的键. default -- 如果指定键的值不存在时,返回该默认值值. 返回值 返回 ...