Python 函数再探(进阶):类型注解、异步协程、面向对象入门
·
前言
本文依次讲解了 Python 进阶基础,函数类型注解、async 异步协程、面向对象基础、__init__初始化魔法方法四块核心内容。本文结合笔者之前的函数文章,练习代码梳理知识点,记录原理、代码示例以及容易踩坑的问题,适合从基础语法向工程化代码过渡的开发者。
目录
二、异步协程 async/await(50. 异步函数.py)
一、函数类型注解(函数的注解)
作用
类型注解不是强制类型校验,仅作为提示,方便 IDE 识别代码、团队协作阅读,静态检测工具(mypy)可以依靠注解检查类型错误。
基础语法
python
运行
"""
文档注释:描述模块/函数整体作用
函数注解:标注形参、返回值的数据类型
"""
def my_print(datas: list[int], obj: dict[str, int | str], n: int = 100) -> None:
print(datas)
print(obj)
print(n)
return None
# 调用测试
my_print(datas=[1, 2, 3], obj={"a": 1, "b": "2"})
datas: list[int]:代表参数 datas 是整数列表dict[str, int | str]:字典 key 为字符串,value 可以是 int 或者 str-> None:标注函数无返回值
⚠️注意:Python 运行时不会强制校验类型,传错数据不会直接报错,仅起到规范提示作用。
二、异步协程 async/await(50. 异步函数.py)
核心概念
sync:同步,代码顺序执行,任务阻塞时原地等待;async:用来定义异步协程函数;await:只能写在async函数内部,交出 CPU 使用权,等待耗时 IO 操作;- 协程对象:直接调用
async def函数不会执行代码,仅仅生成协程对象,必须借助asyncio启动。
完整示例代码
python
运行
import asyncio
import time
async def task2():
while True:
await asyncio.sleep(1)
print(f"第一 {time.time()}")
async def task3():
while True:
await asyncio.sleep(1)
print(f"第二 {time.time()}")
async def task4():
while True:
await asyncio.sleep(1)
print(f"第三 {time.time()}")
async def main():
c1 = task2()
c2 = task3()
c3 = task4()
# 并发运行多个协程任务
await asyncio.gather(c1,c2,c3)
# 程序入口,启动协程
asyncio.run(main())
常见坑
python
运行
# ❌错误写法,仅仅创建协程,代码不会运行
res = task2()
# ✅正确:必须通过asyncio.run / gather 驱动协程执行
异步适合IO 密集型场景(网络请求、文件读写),不适合大量 CPU 计算任务。
三、面向对象基础:类与实例(51. 面向对象.py)
两大编程思想对比
- 面向过程:聚焦步骤流程,一行行堆叠代码;
- 面向对象:聚焦事物抽象,把数据 + 操作数据的方法封装到类中,通过实例调用功能。
类和实例基础概念
- 类(Class):抽象模板,代表一类事物(模板);
- 实例(Instance):根据类创建出来的具体对象。
python
运行
# Python内置类演示
a = int(10)
b = int(20)
print(a, type(a))
# 自定义类
class Person:
pass
# 创建实例
p1 = Person()
p2 = Person()
# 获取类名称、文档字符串
print(Person.__name__, Person.__doc__)
所有变量本质都是某个类的实例,int、list、str全部是 Python 内置类。
四、初始化魔法函数 init(52. 初始化函数.py)
__init__是什么
魔法方法,创建实例时自动调用,专门用来初始化实例属性。 self代表当前创建的实例对象,类内所有成员方法第一个参数必须写self。
示例 1:Person 人员封装
python
运行
class Person:
def __init__(self,name,age = 50):
# 给实例绑定属性
self.name = name
self.age = age
# 获取属性
def get_name(self):
return self.name
def set_name(self,name):
self.name = name
def get_age(self):
return self.age
def set_age(self,age):
self.age = age
# 创建实例,自动执行__init__
p1 = Person("hjs")
print(p1.get_name(), p1.get_age())
p1.set_age(20)
p1.set_name("hhjs")
print(p1.get_name(), p1.get_age())
设计思路:封装思想,使用 get/set 方法读写属性,隔离外部直接修改内部数据。
示例 2:实战项目 —— 坐标点 + turtle 绘图
需求:定义点类存储坐标,绘图类接收点集合,实现所有点两两连线。
python
运行
import turtle
import random
# 点类:封装单个二维坐标
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def get_x(self):
return self.x
def get_y(self):
return self.y
# 绘图类:接收点列表,实现连线绘图
class Draw:
def __init__(self, points):
self.points = points
def draw_line(self):
turtle.up()
length = len(self.points)
# i<j,避免重复连线
for i in range(length):
for j in range(i+1, length):
turtle.goto(self.points[i].get_x(), self.points[i].get_y())
turtle.down()
turtle.goto(self.points[j].get_x(), self.points[j].get_y())
turtle.up()
turtle.mainloop()
# 随机生成3个坐标点实例
points = [Point(random.randint(-300,300), random.randint(-300,300)) for _ in range(3)]
draw = Draw(points)
draw.draw_line()
遇到的典型报错复盘
AttributeError: 'list' object has no attribute 'get_x' 原因:列表是容器,不能调用 Point 对象的方法,列表内必须存放Point实例。
五、知识点整体总结
- 类型注解:规范代码、提升可读性,工程项目必备;
- async 异步协程:IO 场景提升运行效率,牢记协程必须主动驱动执行;
- 面向对象核心:类与实例,
class定义模板,实例承载真实数据; __init__初始化方法:实例创建时自动执行,self访问实例属性;- 封装思想:数据和对应的操作放在同一个类中,代码职责划分清晰,便于后期扩展维护。
后续拓展学习方向
- 面向对象:继承、多态、私有属性、其他魔法方法;
- 协程进阶:任务异常处理、信号量、网络爬虫实战;
- 类型注解进阶:泛型、Protocol 协议类型;
更多推荐



所有评论(0)