Python 高级阶段快速复习
Python 高级阶段快速复习
用途:快速过一遍 PPT 核心内容。重点看:概念一句话、语法模板、易错点、典型代码。
0. 总复习路线
- 面向对象基础:类、对象、self、属性、魔法方法。
- 面向对象高级:继承、重写、super、封装、多态、抽象类、类属性/类方法/静态方法。
- OOP 综合案例:学生管理系统,重点是“类怎么拆、数据怎么存、功能怎么循环”。
- 闭包与装饰器:闭包保存外层变量;装饰器在不改原函数的情况下增强功能。
- 深浅拷贝:浅拷贝只拷贝外层;深拷贝连嵌套对象也复制。
- 网络编程:IP、端口、协议;TCP;socket;服务端/客户端流程。
- 进程与线程:多任务、并发/并行、进程资源隔离、线程共享全局变量、互斥锁。
- 迭代器、生成器、property、正则:高级语法和字符串匹配。
1. 面向对象基础
1.1 面向过程 vs 面向对象
| 思维 | 核心 | 例子 |
|---|---|---|
| 面向过程 | 按步骤解决问题 | 第一步开冰箱,第二步放大象,第三步关冰箱 |
| 面向对象 | 找对象,让对象做事 | 冰箱对象有“打开/关闭”方法,大象对象被放进去 |
一句话: 面向对象就是尽量用代码模拟现实世界,把“属性”和“行为”封装到对象中。
1.2 三大特性
| 特性 | 大白话 | 作用 |
|---|---|---|
| 封装 | 把属性和方法放到类里,对外提供接口 | 简化使用,提高安全性 |
| 继承 | 子类复用父类的属性和方法 | 减少重复代码 |
| 多态 | 同一个方法/函数,传入不同对象表现不同 | 解耦、扩展性强 |
1.3 类、对象、self
class Car(object):
def run(self):
print("汽车能跑")
car = Car() # 创建对象/实例化
car.run() # 对象调用方法
- 类:抽象模板,例如汽车图纸。
- 对象:具体实体,例如某一辆车。
- self:指向当前调用方法的对象本身。谁调用方法,
self就是谁。
class Car(object):
def run(self):
print(self) # 当前对象
car1 = Car()
car2 = Car()
car1.run()
car2.run()
易错点:
- 类内部调用自己的属性:
self.属性名 - 类内部调用自己的方法:
self.方法名() - 类外部调用:
对象名.属性名、对象名.方法名()
1.4 对象属性
class Car(object):
def show(self):
print(self.color)
print(self.number)
car = Car()
car.color = "红色" # 类外部添加属性
car.number = 4
car.show() # 类内部通过 self 访问
一般更推荐在 __init__ 中统一初始化属性,而不是随用随加。
1.5 魔法方法
| 方法 | 什么时候自动调用 | 作用 |
|---|---|---|
__init__ |
创建对象时 | 初始化属性 |
__str__ |
print(对象) 时 |
返回对象的字符串描述 |
__del__ |
对象被删除/程序结束时 | 释放资源或观察对象销毁 |
class Car(object):
def __init__(self, color, number):
self.color = color
self.number = number
def __str__(self):
return f"颜色:{self.color},轮胎数:{self.number}"
def __del__(self):
print("对象被删除")
car = Car("Red", 4)
print(car)
del car
记忆: __init__ 管出生,__str__ 管打印,__del__ 管销毁。
1.6 综合小案例思路:烤地瓜
对象:地瓜。
属性:
cook_time:总共烤了多久cook_state:当前状态condiments:调料列表
方法:
cook(time):累计时间,并根据总时间更新状态add_condiments(condiment):添加调料__str__():输出地瓜状态
核心代码:
class SweetPotato(object):
def __init__(self):
self.cook_time = 0
self.cook_state = "生的"
self.condiments = []
def cook(self, time):
self.cook_time += time
if self.cook_time < 3:
self.cook_state = "生的"
elif self.cook_time < 5:
self.cook_state = "半生不熟"
elif self.cook_time < 8:
self.cook_state = "熟了"
else:
self.cook_state = "烤糊了"
def add_condiments(self, condiment):
self.condiments.append(condiment)
def __str__(self):
return f"时间:{self.cook_time},状态:{self.cook_state},调料:{self.condiments}"
2. 面向对象高级
2.1 类的三种写法
class Teacher:
pass
class Teacher():
pass
class Teacher(object):
pass
课件建议重点使用:
class 类名(object):
pass
补充理解:Python 3 中默认继承 object,所以 class A: 和 class A(object): 基本等价,但写 object 更利于初学时理解“所有类最终继承 object”。
2.2 继承
class Father(object):
def __init__(self):
self.sex = "男"
def walk(self):
print("散步")
class Son(Father):
pass
son = Son()
print(son.sex)
son.walk()
- 父类/基类:被继承的类。
- 子类/派生类:继承别人的类。
- 作用:复用代码,减少重复。
- 本质:子类对象可以使用父类的属性和方法。
2.3 单继承与多继承
class Son(Father):
pass
class Son(Father, Mother):
pass
多继承时,如果多个父类有同名属性或方法,默认按继承顺序查找,先找第一个父类。
print(Son.__mro__)
print(Son.mro())
MRO:Method Resolution Order,方法解析顺序。
2.4 重写与调用父类方法
子类定义了和父类同名的方法或属性,就会优先使用子类自己的。
class Father(object):
def make_cake(self):
print("父类配方")
class Son(Father):
def make_cake(self):
print("子类新配方")
子类想调用父类方法:
class Son(Father):
def make_old_cake(self):
super().make_cake()
也可以写:
Father.make_cake(self)
但更推荐 super()。
易错点:
super().方法名()不需要手动传self。父类名.方法名(self)需要手动传self。- 多继承时
super()会按 MRO 走,复杂多继承要谨慎。
2.5 多层继承
class A(object):
pass
class B(A):
pass
class C(B):
pass
C 可以继承 B 的内容,也能间接继承 A 的内容。
2.6 封装与私有属性
私有属性/方法:在名字前加两个下划线 __。
class Person(object):
def __init__(self):
self.__money = 1000
def get_money(self):
return self.__money
def set_money(self, money):
self.__money = money
私有方法:
class Person(object):
def __secret(self):
print("私有方法")
def call_secret(self):
self.__secret()
记忆: 私有成员不能在类外直接访问,一般通过公有方法间接访问。
2.7 多态
多态:同一个调用方式,传入不同子类对象,产生不同效果。
成立条件按课件记:
- 有继承。
- 子类重写父类方法。
- 父类引用指向子类对象,也就是框架函数接收父类类型,实际传入子类对象。
class HeroFighter(object):
def power(self):
return 60
class AdvHeroFighter(HeroFighter):
def power(self):
return 80
class EnemyFighter(object):
def attack(self):
return 70
def object_play(hero: HeroFighter, enemy: EnemyFighter):
if hero.power() > enemy.attack():
print("英雄胜利")
else:
print("英雄失败")
object_play(HeroFighter(), EnemyFighter())
object_play(AdvHeroFighter(), EnemyFighter())
好处: 平台函数 object_play 不需要改,后来新增更强的战机类也能接入,这就是解耦和扩展。
2.8 抽象类/接口思想
抽象类:父类只规定“必须有什么方法”,具体怎么做交给子类。
class Animal(object):
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("汪汪")
一句话: 抽象类像行业标准,子类像不同厂家,各自实现标准。
2.9 类属性、类方法、静态方法
对象属性
每个对象自己一份。
class Phone(object):
def __init__(self):
self.brand = "华为"
类属性
属于类,被所有对象共享。
class Person(object):
count = 0
print(Person.count) # 推荐
类方法
class Dog(object):
@classmethod
def eat(cls):
print("小狗都喜欢骨头")
Dog.eat()
- 第一个参数是
cls,代表类本身。 - 常用于访问/修改类属性。
静态方法
class Game(object):
@staticmethod
def show_menu():
print("1.开始 2.暂停 0.退出")
Game.show_menu()
- 不需要
self,也不需要cls。 - 只是放在类里的普通工具函数。
3. 学生管理系统综合案例
3.1 项目拆分
推荐文件结构:
StudentManagerSystem/
├── main.py # 程序入口
├── student.py # 学生类
└── studentcms.py # 管理系统类
角色:
Student:表示一个学生。StudentCms:管理学生信息。
3.2 Student 类
class Student(object):
def __init__(self, name, age, gender, mobile, description):
self.name = name
self.age = age
self.gender = gender
self.mobile = mobile
self.description = description
def __str__(self):
return f"{self.name}, {self.age}, {self.gender}, {self.mobile}, {self.description}"
3.3 管理系统核心属性
class StudentCms(object):
def __init__(self):
self.student_list = [] # 列表中存学生对象
3.4 主循环框架
def start(self):
while True:
self.show_operate_view()
number = int(input("请输入操作序号:"))
if number == 1:
self.add_student()
elif number == 2:
self.update_student()
elif number == 3:
self.delete_student()
elif number == 4:
self.query_student()
elif number == 5:
self.show_all_student()
elif number == 6:
self.save_student()
elif number == 0:
break
else:
print("序号不存在")
3.5 增删改查思路
添加
def add_student(self):
name = input("姓名:")
age = int(input("年龄:"))
gender = input("性别:")
mobile = input("联系方式:")
description = input("简介:")
student = Student(name, age, gender, mobile, description)
self.student_list.append(student)
删除
def delete_student(self):
name = input("请输入要删除的姓名:")
for student in self.student_list:
if student.name == name:
self.student_list.remove(student)
print("删除成功")
break
else:
print("学生不存在")
修改
def update_student(self):
name = input("请输入要修改的姓名:")
for student in self.student_list:
if student.name == name:
student.age = int(input("新年龄:"))
student.gender = input("新性别:")
student.mobile = input("新联系方式:")
student.description = input("新简介:")
break
else:
print("学生不存在")
查询
def query_student(self):
name = input("请输入要查询的姓名:")
for student in self.student_list:
if name in student.name:
print(student)
break
else:
print("学生不存在")
显示全部
def show_all_student(self):
for student in self.student_list:
print(student)
3.6 保存与加载
保存对象时不能直接保存对象内存地址,要转成字典。
def save_student(self):
with open("student.data", "w", encoding="utf-8") as f:
data = [student.__dict__ for student in self.student_list]
f.write(str(data))
加载:
def load_student(self):
try:
with open("student.data", "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
content = "[]"
if not content:
content = "[]"
data_list = eval(content)
self.student_list = [
Student(d["name"], d["age"], d["gender"], d["mobile"], d["description"])
for d in data_list
]
易错点:
- 课件中有的地方用了
student_datas,有的地方用了student_list,实际写代码时必须统一变量名。 eval()学习案例可以用,真实开发更推荐json。for ... else:循环没有被break打断,才执行else。
3.7 main.py
from studentcms import StudentCms
if __name__ == "__main__":
cms = StudentCms()
cms.start()
4. 闭包、装饰器、深浅拷贝
4.1 闭包
闭包作用:保存外部函数中的变量,让它在外部函数执行完后仍然能被内部函数使用。
闭包三条件:
- 有函数嵌套。
- 内部函数使用外部函数变量。
- 外部函数返回内部函数。
def func_out(num1):
def func_inner(num2):
print(num1 + num2)
return func_inner
f = func_out(10)
f(1) # 11
4.2 nonlocal
内部函数要修改外部函数变量时,用 nonlocal。
def func_out():
a = 100
def func_inner():
nonlocal a
a += 1
print(a)
return func_inner
global:声明全局变量。nonlocal:声明外层函数的局部变量。
4.3 装饰器
装饰器作用:不修改原函数代码的前提下,给原函数增加额外功能。
装饰器本质:闭包函数。
def check(fn):
def inner():
print("登录验证")
fn()
return inner
@check
def comment():
print("发表评论")
comment()
解释器遇到:
@check
def comment():
pass
等价于:
comment = check(comment)
4.4 通用装饰器模板
原函数有参数、有返回值时,内部函数也要接收参数并返回结果。
def decorator(fn):
def inner(*args, **kwargs):
print("额外功能")
return fn(*args, **kwargs)
return inner
一句话: 原函数有没有参数、有没有返回值,装饰器内部函数就要对应处理。
4.5 多个装饰器
def check_user(fn):
def inner():
print("用户名密码验证")
fn()
return inner
def check_code(fn):
def inner():
print("验证码验证")
fn()
return inner
@check_user
@check_code
def comment():
print("发表评论")
装饰过程:离函数最近的先装饰,由内到外。
等价于:
comment = check_user(check_code(comment))
调用执行时:外层先执行。
4.6 带参数的装饰器
带参数装饰器 = 外面再包一层函数,用来接收装饰器参数。
def logging(flag):
def decorator(fn):
def inner(a, b):
if flag == "+":
print("正在加法计算")
elif flag == "-":
print("正在减法计算")
return fn(a, b)
return inner
return decorator
@logging("+")
def add(a, b):
return a + b
@logging("-")
def sub(a, b):
return a - b
记忆结构:
def 外层函数(装饰器参数):
def 装饰器(原函数):
def 内层函数(*args, **kwargs):
return 原函数(*args, **kwargs)
return 内层函数
return 装饰器
4.7 浅拷贝与深拷贝
import copy
b = copy.copy(a) # 浅拷贝
c = copy.deepcopy(a) # 深拷贝
| 类型 | 含义 | 嵌套对象是否独立 |
|---|---|---|
| 赋值 | 多个变量指向同一个对象 | 不独立 |
| 浅拷贝 | 只复制最外层对象 | 内层嵌套对象仍共享 |
| 深拷贝 | 递归复制所有层级 | 基本独立 |
例子:
import copy
a = [1, 2, [3, 4]]
b = copy.copy(a)
c = copy.deepcopy(a)
a[2].append(5)
print(b) # [1, 2, [3, 4, 5]],受影响
print(c) # [1, 2, [3, 4]],不受影响
重点: 浅拷贝最怕“列表里面还有列表”这种嵌套可变对象。
5. 网络编程
5.1 网络编程三要素
| 要素 | 作用 | 类比 |
|---|---|---|
| IP 地址 | 找到哪台电脑 | 家庭地址 |
| 端口 | 找到电脑上的哪个程序 | 门牌/窗口 |
| 协议 | 通信规则 | 双方都能听懂的语言 |
端口号:
- 0~1023:知名端口。
- 1024~65535:动态端口,开发程序常用。
5.2 TCP 协议
TCP:传输控制协议,特点是面向连接、可靠传输、基于字节流。
通信流程:
- 建立连接。
- 传输数据。
- 关闭连接。
三次握手:建立连接。
- 客户端请求连接。
- 服务端确认收到请求。
- 客户端再次确认,连接建立。
四次挥手:断开连接。
- A 请求关闭。
- B 确认 A 的关闭请求。
- B 请求关闭。
- A 确认 B 的关闭请求。
5.3 socket
socket 是进程间网络通信的工具。
import socket
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
AF_INET:IPv4。SOCK_STREAM:TCP。
网络传输的是 bytes,字符串要编码/解码:
s = "你好"
b = s.encode("utf-8")
s2 = b.decode("utf-8")
5.4 TCP 服务端流程
- 创建 socket。
- 绑定 IP 和端口。
- 设置监听。
- 等待客户端连接。
- 接收/发送数据。
- 关闭连接 socket。
- 关闭服务端 socket。
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server.bind(("", 8888))
server.listen(128)
conn, addr = server.accept()
print("客户端地址:", addr)
data = conn.recv(1024)
print(data.decode("utf-8"))
conn.send("收到".encode("utf-8"))
conn.close()
server.close()
5.5 TCP 客户端流程
- 创建 socket。
- 连接服务端。
- 发送/接收数据。
- 关闭 socket。
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 8888))
client.send("hello".encode("utf-8"))
data = client.recv(1024)
print(data.decode("utf-8"))
client.close()
易错点:
- 客户端连接的端口必须和服务端绑定的端口一致。
accept()前的服务端 socket 是“被动套接字”,只负责接收连接。accept()返回的新 socket 才负责和具体客户端通信。recv()是阻塞等待;客户端关闭后,服务端recv()可能返回长度为 0 的数据。- 服务端重启端口没释放,可加:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
6. 进程
6.1 多任务、并发、并行
| 概念 | 含义 |
|---|---|
| 多任务 | 同一时间段内执行多个任务,用户感觉像同时运行 |
| 并发 | 单核 CPU 交替执行多个任务 |
| 并行 | 多核 CPU 真正同时执行多个任务 |
6.2 进程概念
进程是操作系统进行资源分配和调度运行的基本单位,也可理解为“正在运行的程序”。
特点:
- 一个程序运行后至少有一个主进程。
- 主进程可以创建子进程。
- 进程之间默认不共享全局变量。
6.3 创建多进程
import multiprocessing
def task():
print("任务执行")
if __name__ == "__main__":
p = multiprocessing.Process(target=task)
p.start()
带参数:
def coding(num, name):
for i in range(num):
print(f"{name}写第{i}行代码")
p = multiprocessing.Process(target=coding, args=(3, "小明"))
p.start()
def music(count, name):
print(count, name)
p = multiprocessing.Process(target=music, kwargs={"count": 3, "name": "小明"})
p.start()
6.4 进程编号
import os
import multiprocessing
print(os.getpid()) # 当前进程 ID
print(os.getppid()) # 父进程 ID
print(multiprocessing.current_process().pid)
6.5 进程注意点
进程之间不共享全局变量
import multiprocessing
my_list = []
def write_data():
my_list.append(1)
print("write:", my_list)
def read_data():
print("read:", my_list)
子进程会复制主进程资源,名字相同但不是同一块内存。
主进程默认等待子进程结束
p = multiprocessing.Process(target=task)
p.start()
主进程结束前,通常会等子进程执行完。
不想等:
p.daemon = True # 主进程结束,子进程跟着销毁
p.start()
或:
p.terminate() # 手动终止子进程,不太推荐
7. 线程
7.1 线程概念
- 进程是资源分配的基本单位。
- 线程是 CPU 调度的基本单位。
- 一个进程至少有一个线程,默认叫主线程。
- 线程必须依附于进程存在。
7.2 创建多线程
import threading
def task():
print("线程任务")
thread = threading.Thread(target=task)
thread.start()
带参数:
threading.Thread(target=coding, args=(3, "小明")).start()
threading.Thread(target=music, kwargs={"count": 3, "name": "小明"}).start()
7.3 线程注意点
- 线程执行顺序是无序的,由 CPU 调度决定。
- 主线程默认等待所有子线程执行完再结束。
- 线程之间共享全局变量。
- 共享全局变量可能出现数据安全问题。
守护线程:
thread = threading.Thread(target=task, daemon=True)
thread.start()
7.4 线程共享全局变量
import threading
my_list = []
def write_data():
my_list.append(1)
threading.Thread(target=write_data).start()
同一进程内的多个线程共享全局变量,所以一个线程修改后,其他线程能看到。
7.5 数据安全与互斥锁
多个线程同时修改同一个全局变量,可能导致结果错误。
互斥锁:同一时刻只允许一个线程操作共享数据。
import threading
g_num = 0
mutex = threading.Lock()
def add_num():
global g_num
mutex.acquire()
for _ in range(100000):
g_num += 1
mutex.release()
更安全写法:
def add_num():
global g_num
with mutex:
for _ in range(100000):
g_num += 1
死锁:线程一直等对方释放锁,程序卡住。
易错点: 上锁后必须释放锁,否则容易死锁。
7.6 进程 vs 线程
| 对比 | 进程 | 线程 |
|---|---|---|
| 单位 | 资源分配基本单位 | CPU 调度基本单位 |
| 是否独立 | 独立 | 依附于进程 |
| 全局变量 | 默认不共享 | 共享 |
| 开销 | 大 | 小 |
| 稳定性 | 更强,一个进程挂了不一定影响其他进程 | 一个线程异常可能影响整个进程 |
| 多核利用 | 可以更好利用多核 | CPython 中 CPU 密集型受 GIL 限制 |
按课件记:多进程资源开销大但稳定性强;多线程资源开销小但要注意共享数据安全。
8. 迭代器、生成器、property、正则表达式
8.1 迭代器
迭代器是实现了 __iter__() 和 __next__() 的对象。
class MyIterator(object):
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current > self.end:
raise StopIteration
value = self.current
self.current += 1
return value
for num in MyIterator(1, 5):
print(num)
特点:
- 手动管理状态。
- 可以用
next()或for遍历。 - 惰性计算,适合大数据/流式数据。
8.2 生成器
生成器是更简单的迭代器写法。
生成器推导式
g = (i * 2 for i in range(5))
for value in g:
print(value)
注意:小括号里是生成规则,不是一次性存好所有数据。
yield 生成器
def my_generator(n):
for i in range(n):
print("开始生成")
yield i
print("完成一次")
yield 作用:
- 返回
yield后面的值。 - 暂停函数执行,下次从暂停位置继续。
for 循环会自动处理 StopIteration,所以比手动 next() 更方便。
8.3 迭代器 vs 生成器
| 对比 | 迭代器 | 生成器 |
|---|---|---|
| 实现方式 | 手写 __iter__ 和 __next__ |
使用 yield |
| 状态管理 | 自己管理 | Python 自动管理 |
| 代码量 | 较多 | 简洁 |
| 场景 | 复杂迭代逻辑 | 简洁生成数据、大数据按需生成 |
8.4 property 属性
作用:把方法当成属性使用,简化调用,同时可控制读写逻辑。
装饰器方式
class Person(object):
def __init__(self):
self.__age = 0
@property
def age(self):
return self.__age
@age.setter
def age(self, new_age):
self.__age = new_age
p = Person()
print(p.age)
p.age = 18
类属性方式
class Person(object):
def __init__(self):
self.__age = 0
def get_age(self):
return self.__age
def set_age(self, new_age):
self.__age = new_age
age = property(get_age, set_age)
8.5 正则表达式与 re 模块
正则表达式:用特殊符号描述字符串匹配规则。
常见作用:
- 数据验证:手机号、邮箱、IP。
- 数据检索:爬虫提取内容。
- 数据替换:敏感词过滤。
- 数据隐藏:手机号脱敏。
re 三步:
import re
result = re.match(pattern, string)
if result:
print(result.group())
8.6 match、search、sub
re.match(pattern, string) # 从字符串开头匹配
re.search(pattern, string) # 扫描整个字符串,返回第一个匹配
re.sub(pattern, repl, string) # 替换
例子:
import re
result = re.search(r"\d.*", "city:1beijing2.shanghai")
print(result.group()) # 1beijing2.shanghai
8.7 单字符匹配
| 符号 | 含义 |
|---|---|
. |
任意一个字符,除了换行符 |
[abc] |
匹配 a/b/c 中任意一个 |
[a-z] |
匹配小写字母 |
\d |
数字,等价于 [0-9] |
\D |
非数字 |
\s |
空白字符,空格、tab 等 |
\S |
非空白 |
\w |
字母、数字、下划线、汉字 |
\W |
非 \w |
8.8 多字符匹配
| 符号 | 含义 |
|---|---|
* |
前一个字符出现 0 次或多次 |
+ |
前一个字符出现 1 次或多次 |
? |
前一个字符出现 0 次或 1 次 |
{m} |
前一个字符出现 m 次 |
{m,n} |
前一个字符出现 m 到 n 次 |
易错点: {2,5} 逗号后不要写空格。
8.9 开头、结尾、取反
| 符号 | 含义 |
|---|---|
^ |
匹配字符串开头 |
$ |
匹配字符串结尾 |
[^abc] |
匹配除了 a/b/c 之外的字符 |
re.match(r"^\d.*\d$", "11itcast22")
表示:以数字开头,以数字结尾,中间任意内容。
8.10 分组
result = re.match(r"(qq):([1-9]\d{4,11})", "qq:10567")
print(result.group()) # 全部:qq:10567
print(result.group(1)) # qq
print(result.group(2)) # 10567
邮箱例子:
result = re.match(r"[a-zA-Z0-9_]{4,20}@(163|126|qq)\.com", "hello@qq.com")
分组引用:
result = re.match(r"<([a-zA-Z1-6]{1,10})>.*</\1>", "<html>hh</html>")
\1 表示引用第一个分组匹配到的内容,保证前后标签一致。
9. 最后速记清单
9.1 必背语法模板
# 类
class 类名(object):
def __init__(self):
pass
# 继承
class 子类(父类):
pass
# 调父类
super().方法名()
# 私有属性
self.__属性名 = 值
# 类方法
@classmethod
def 方法名(cls):
pass
# 静态方法
@staticmethod
def 方法名():
pass
# 闭包
def outer():
x = 1
def inner():
print(x)
return inner
# 通用装饰器
def decorator(fn):
def inner(*args, **kwargs):
return fn(*args, **kwargs)
return inner
# 进程
multiprocessing.Process(target=任务名).start()
# 线程
threading.Thread(target=任务名).start()
# socket
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 正则
result = re.match(pattern, string)
if result:
result.group()
9.2 高频易错点
self不是随便写的,它代表当前对象。__init__创建对象时自动执行,不是手动调用的普通函数。__str__必须return字符串,不能直接print。- 子类重写父类方法后,优先调用子类方法。
super().方法()不写self。- 私有属性
__xxx类外不能直接访问,应写get_xxx/set_xxx。 - 装饰器如果原函数有返回值,内部函数也必须
return。 - 多个装饰器:装饰时由内到外,执行时由外到内。
- 浅拷贝遇到嵌套可变对象,内层仍然共享。
- TCP 客户端连接端口必须和服务端绑定端口一致。
- 进程不共享全局变量,线程共享全局变量。
- 线程共享数据要加锁,加锁后必须释放锁。
re.match()从开头匹配;想从中间找用re.search()。- 正则里
.想表示真正的小数点,要写\.或使用原始字符串r"\."。
9.3 用一句话串起来
Python 高级这一组课的主线是:先用面向对象把现实事物抽象成类和对象,再用继承、封装、多态提高代码复用和扩展性;遇到函数增强用闭包和装饰器,遇到对象复制要区分浅拷贝和深拷贝;做网络通信要掌握 IP、端口、协议、socket、TCP;做多任务要区分进程和线程;处理大数据遍历用迭代器/生成器;处理字符串规则匹配用正则表达式。