当前位置:网站首页>Any 与 TypeVar,让 IDE 的自动补全更好用
Any 与 TypeVar,让 IDE 的自动补全更好用
2022-06-24 09:51:00 【VIP_CQCRE】
这是「进击的Coder」的第 650 篇技术分享
作者:kingname
来源:未闻 Code
“
阅读本文大概需要 6 分钟。
”相信有很多同学在写 Python 的时候,会使用类型标注来提高代码的可读性,同时还能帮助 IDE 实现自动补全。
假设我们现在获得了一个对象,这个对象可能是列表也可能是生成器,我写一个函数,获取它的第一个元素。代码很简单:
from typing import Iterator
from contextlib import suppress
class People:
def __init__(self, name):
self.name = name
def eat(self):
print(f'{self.name}正在吃饭')
def walk(self):
print(f'{self.name}正在走路')
def get_first_element(ele_list):
if isinstance(ele_list, list):
return ele_list[0] if ele_list else None
if isinstance(ele_list, Iterator):
with suppress(Exception):
value = next(ele_list)
return value
return None
if __name__ == '__main__':
kingname = People('kingname')
pm = People('pm')
people_list = [kingname, pm]
obj = get_first_element(people_list)
if obj:
print(obj.)代码写好了,但是当我获取第一个元素,想打印它里面的数据的时候,我发现我忘记了 People 这个类有哪些属性了,而此时 PyCharm 的自动补全也失效了,我不得不把代码往回翻,去寻找 People 定义的位置,效率非常低。如下图所示。

如果我们使用了类型标注,就能解决这个问题:

这个常规用法,大家肯定都知道。
现在问题来了,我们除了People类,还有Cat类,并且列表里面的元素可能全是People类的实例,也可能全是Cat类实例,这种情况怎么办呢?
首先你遇到了第一个问题,get_first_element的参数的类型标注怎么写?
你可能会写成这样:
def get_first_element(ele_list: Union[List[Union[People, Cat]], Iterator[Union[People, Cat]]])那如果还有一个Dog类呢?
为了简化操作,你可能会用Any,类型,于是get_first_element变成了下面这样:
def get_first_element(ele_list: Union[List[Any], Iterator[Any]]) -> Optional[Any]:
if isinstance(ele_list, list):
return ele_list[0] if ele_list else None
if isinstance(ele_list, Iterator):
with suppress(Exception):
value = next(ele_list)
return value
return None现在你发现问题又来了,PyCharm 的自动补全又坏了。因为 Any 是任何类型,所以在代码运行前,它其实不知道你返回的是什么东西。如下图所示:

这种情况下,你就需要使用 Python 类型标注中的泛型了。我们知道,泛型是静态语言中的概念,Python 由于使用了类型标注,也有了类型。于是也就借用了这个概念。
我们来看看怎么使用它:
from typing import TypeVar
T = TypeVar('T')注意这里的变量名T和 TypeVar 的参数'T'可以同时写成任意字符串,但变量名要与参数保持一致。例如:
GodType = TypeVar('GodType')然后把 T 当作Any一样使用就可以。我们来看看效果:

可以看到,PyCharm 又能自动补全了。使用TypeVar,可以告诉 PyCharm,返回的类型跟传入参数中的T对应位置的类型保持一致。例如传入参数中,T在List[T]或者Generator[T]中,所以返回的参数需要与列表中的元素或者生成器中的元素类型保持一致。
我们用 Cat 生成器来测试一下,发现也能自动补全:

还有更厉害的,如果我的列表里面既有Cat的实例,又有People的实例怎么办?这个时候,PyCharm 会直接把两个实例的可能补全都给你列出来:


End
崔庆才的新书《Python3网络爬虫开发实战(第二版)》已经正式上市了!书中详细介绍了零基础用 Python 开发爬虫的各方面知识,同时相比第一版新增了 JavaScript 逆向、Android 逆向、异步爬虫、深度学习、Kubernetes 相关内容,同时本书已经获得 Python 之父 Guido 的推荐,目前本书正在七折促销中!
内容介绍:《Python3网络爬虫开发实战(第二版)》内容介绍

扫码购买


点个在看你最好看

边栏推荐
- Practice sharing of packet capturing tool Charles
- Outils de capture de paquets
- 抓包工具charles實踐分享
- [IEEE publication] 2022 International Conference on service robots (iwosr 2022)
- Younger sister Juan takes you to learn JDBC --- 2-day sprint Day1
- Niuke-top101-bm29
- System design: load balancing
- 23. opencv - image mosaic project
- 喜欢就去行动
- [resource sharing] 2022 International Conference on Environmental Engineering and Biotechnology (coeeb 2022)
猜你喜欢

26. delete duplicates of ordered array

Apple's legendary design team disbanded after jobs refused to obey cook

Spark submission parameter -- use of files

HBuilder制作英雄皮肤抽奖小游戏

charles抓包工具使用教程

P5.js paper crane animation background JS special effect

【Energy Reports期刊发表】2022年能源与环境工程国际会议(CFEEE 2022)

26.删除有序数组的重复项

机械臂速成小指南(二):机械臂的应用

Quick completion guide for mechanical arm (I): development overview of mechanical arm
随机推荐
Five methods of JS array summation
How to convert an array to an object, and how to convert an object to an array
JMeter interface test tool foundation - badboy tool
Common third-party UI frameworks
283. move zero
什么是递归?
Thread operation principle
服乔布斯不服库克,苹果传奇设计团队解散内幕曝光
Maui的学习之路 -- 开篇
Hill sorting graphic explanation + code implementation
机械臂速成小指南(三):机械臂的机械结构
Leetcode interview question 16.06: minimum difference
機械臂速成小指南(二):機械臂的應用
顺丰科技智慧物流校园技术挑战赛(2022/06/19)【AK】
Which map navigation is easy to use and accurate?
Quick completion guide for manipulator (III): mechanical structure of manipulator
Four methods of object merging and four methods of object merging in JS
Rising bubble canvas breaking animation JS special effect
The difference between the sleep () method and the wait () method of a thread
机械臂速成小指南(零):指南主要内容及分析方法