python typing_Python标准库--typing

作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明。谢谢!

1 模块简介

Python 3.5 增加了一个有意思的库--typing。这将会给Python增加了类型暗示。类型暗示是一种可以将你的函数变量声明为一种特定类型的声明。当然,类型暗示并不是绑定。它仅仅是暗示,所以这种机制并不能阻止工程师传入他们不应该传入的参数。这个就是Python。你可以在PEP 484中阅读类型暗示的说明,或者你也可以在PEP 483 阅读背后的理论。

2 模块使用

2.1 基本使用

下面让我们看一个简单的例子,

>>> def some_function(number:int,name:str) -> None:

... print("%s entered %s"%(name,number))

>>> some_function(13,"Mike")

Mike entered 13

这就意味着some_function函数认为两个变量中第一个变量是整数,第二个变量是字符串。你或许可能已经注意到,我们已经暗示这个函数将会返回None。

请允许我们倒退一下,先写一个普通的函数。然后我们将会添加类型暗示。在下面这个例子中,我们写了一个函数,这个函数的入参是一个列表和一个变量name,name的类型是字符串。这个函数的功能就是检查变量name是否在这个列表中,然后返回一个适当的布尔值。

def process_data(my_list,name):

if name in my_list:

return True

else:

return False

if __name__ == "__main__":

my_list = ["Mike","Nick","Toby"]

print(process_data(my_list,"Mike"))

print(process_data(my_list,"John"))

下面我们为这个函数添加类型暗示。

def process_data(my_list:list,name:str) -> bool:

return name in my_list

if __name__ == "__main__":

my_list = ["Mike","Nick","Toby"]

print(process_data(my_list,"Mike"))

print(process_data(my_list,"John"))

在这段代码中,我们暗示第一个变量是列表类型,第二个变量是字符串类型,返回值是布尔类型。

根据PEP 484 ,“类型暗示可能会是内置的类(包括定义在标准库或者第三方扩展库),抽象出的基类,types模块中可获得类型和用户定义的类”。这就意味着我们可以创建我们自己的类,然后添加一个暗示。

class Fruit:

def __init__(self,name,color):

self.name = name

self.color = color

def salad(fruit_one:Fruit,fruit_two:Fruit) -> list:

print (fruit_one.name)

print (fruit_two.name)

return [fruit_one,fruit_two]

if __name__ == "__main__":

f = Fruit("orange","orange")

f2 = Fruit("apple","red")

salad(f,f2)

在这段代码中,我们首先创建一个类Fruit,然后定一个函数,将两个入参暗示为类Fruit的实例并返回一个列表对象。另一个我认为有意思的话题就是你可以创建一个别名。下面是一个超级简单的例子。

import string

Animal = string

def zoo(animal:Animal,number:int) -> None:

print("The zoo has %s %s" % (number,animal))

if __name__ == "__main__":

zoo("Zebras",10)

你可以能已经猜到,我们就是将变量Animal作为string类型的别名。然后我们使用别名Animal向我们的函数添加一个暗示。

2.2 类型暗示与重载函数

在你的代码中,我认为类型暗示可以在重载函数这块做的很好。我们已经在 functools 模块中学习了函数重载。我们以这部分中的相加函数为例,看看利用类型暗示如何做的更好。下面是原始的代码,

import string

from functools import singledispatch

@singledispatch

def add(a,b):

raise NotImplementedError("Unsupport type")

@add.register(int)

def _(a,b):

print("Fist argument is of type ",type(a))

print (a+b)

@add.register(string)

def _(a,b):

print("Fist argument is of type ",type(a))

print (a+b)

@add.register(list)

def _(a,b):

print("Fist argument is of type ",type(a))

print (a+b)

在这个例子中,如果你理解Python的函数重载是如何工作的,函数的第一个变量的意义就很明显了。但是我们并不知道第二个变量应该是什么。我们可以推测,但是在Python中它最好是明确的而非隐含的。所以我们需要添加一些类型暗示。

import string

from functools import singledispatch

@singledispatch

def add(a,b):

raise NotImplementedError("Unsupport type")

@add.register(int)

def _(a:int,b:int) -> int:

print("Fist argument is of type ",type(a))

print (a+b)

return a+b

@add.register(string)

def _(a:string,b:string) -> string:

print("Fist argument is of type ",type(a))

print (a+b)

return a+b

@add.register(list)

def _(a:list,b:list) -> list:

print("Fist argument is of type ",type(a))

print (a+b)

return a+b

现在我们已经添加了一些类型暗示,我们仅仅通过观察函数的定义就可以知道变量应该是什么类型。在类型暗示添加之前,你需要在函数的docstring中说明变量类型,由于我们已经有了类型暗示,我们就不再需要添加docstring等信息。

我在一些Python代码中已经很少添加文档了,即使函数和方法定义中仅仅有类型暗示,依然可以更容易的理解。类型暗示并不能替代一个好的说明文档,但是通过使用它,在后续开发过程中可以让我们更容易地理解我们的代码。

2.2 总结

当我第一次听说类型暗示,我就被它迷住。它的概念很简洁,我可以很明确地使用它。第一个使用场景就是可以作为你的代码的自文档。我看过很多代码,它们很难告诉你一个函数或者类的接收参数类型,虽然类型暗示并不会强制任何事,它却会让这些有歧义的代码更加清晰。如果一些Python IDE添加了一个可选的标志位,这将会检查你的代码的类型暗示,最终会确保你可以正确调用你的代码。

我非常乐意推荐阅读Python的 官方文档,那里有很多信息。PEP规范也包含了很多细节。

3 Reference

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值