Python高阶
·
目录
一、闭包
1.1 什么是闭包
定义:在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,这个内部函数称为闭包。
def outer(logo):
def inner(msg):
print(f"{logo}: {msg}")
return inner
# 创建闭包函数
fn1 = outer("黑马程序员")
fn2 = outer("传智教育")
fn1("你好") # 黑马程序员: 你好
fn2("你好") # 传智教育: 你好
1.2 nonlocal关键字
在内部函数中修改外部函数的变量时,需要使用 nonlocal 声明。
def outer():
money = 0
def inner(num):
nonlocal money # 声明要修改外部变量
money += num
print(f"当前余额: {money}")
return money
return inner
atm = outer()
atm(100) # 当前余额: 100
atm(50) # 当前余额: 150
1.3 闭包的优缺点
| 优点 | 缺点 |
|---|---|
| 无需全局变量,持续访问和修改值 | 额外内存占用 |
| 作用域封闭,难以被误修改 | 内部函数持续引用外部变量 |
二、装饰器
2.1 什么是装饰器
定义:在不破坏目标函数原有代码和功能的前提下,为目标函数增加新功能。装饰器本质上也是一种闭包。
# 装饰器函数
def outer(func):
def inner():
print("我要睡觉了") # 新增功能
func() # 执行原函数
print("我起床了") # 新增功能
return inner
# 普通函数
def sleep():
print("睡觉中...")
# 使用装饰器
sleep = outer(sleep)
sleep()
输出:
我要睡觉了 睡觉中... 我起床了
2.2 语法糖写法(@符号)
def outer(func):
def inner():
print("我要睡觉了")
func()
print("我起床了")
return inner
@outer # 等价于 sleep = outer(sleep)
def sleep():
print("睡觉中...")
sleep()
# 输出:我要睡觉了 / 睡觉中... / 我起床了
2.3 带参数的装饰器
def outer(func):
def inner(*args, **kwargs):
print("方法执行前")
result = func(*args, **kwargs)
print("方法执行后")
return result
return inner
@outer
def add(a, b):
return a + b
print(add(3, 5))
# 输出:
# 方法执行前
# 方法执行后
# 8
三、设计模式
3.1 单例模式
定义:确保一个类只有一个实例,并提供一个全局访问点。
适用场景:工具类、配置类、数据库连接池等只需要一个实例的场景。
# 方式1:使用模块(Python天然单例)
# my_singleton.py
class Singleton:
def __init__(self):
self.value = 0
singleton = Singleton()
# 其他文件导入
from my_singleton import singleton
# singleton 始终是同一个对象
# 方式2:使用装饰器
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class Database:
def __init__(self):
self.connected = False
db1 = Database()
db2 = Database()
print(db1 is db2) # True
3.2 工厂模式
定义:将对象的创建由原生类本身转换到特定的工厂方法来创建。
适用场景:需要大量创建同类型对象时。
# 产品类
class Dog:
def speak(self):
return "汪汪汪"
class Cat:
def speak(self):
return "喵喵喵"
class Duck:
def speak(self):
return "嘎嘎嘎"
# 工厂类
class AnimalFactory:
@staticmethod
def create_animal(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
elif animal_type == "duck":
return Duck()
else:
raise ValueError(f"Unknown animal type: {animal_type}")
# 使用工厂创建对象
animal = AnimalFactory.create_animal("dog")
print(animal.speak()) # 汪汪汪
工厂模式优点:
-
统一入口,易于代码维护
-
修改时只需修改工厂类
四、多线程
4.1 进程与线程
| 概念 | 说明 |
|---|---|
| 进程 | 程序在操作系统内运行,是资源分配的基本单位 |
| 线程 | 进程的实际工作单位,是CPU调度的基本单位 |
| 并行执行 | 同一时间做不同的工作 |
4.2 threading模块
import threading
import time
def sing():
for i in range(3):
print(f"唱歌第{i+1}次")
time.sleep(1)
def dance():
for i in range(3):
print(f"跳舞第{i+1}次")
time.sleep(1)
# 创建线程
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
# 启动线程
t1.start()
t2.start()
# 等待线程结束
t1.join()
t2.join()
print("所有线程执行完毕")
4.3 带参数的多线程
import threading
def say(message, count):
for i in range(count):
print(message)
# 使用args传参(元组,按顺序)
t1 = threading.Thread(target=say, args=("你好", 3))
# 使用kwargs传参(字典,按参数名)
t2 = threading.Thread(target=say, kwargs={"message": "Hello", "count": 2})
t1.start()
t2.start()
五、网络编程(Socket)
5.1 什么是Socket
Socket(套接字)是进程之间通信的工具,负责进程之间的网络数据传输。
5.2 服务端开发
import socket
# 1. 创建socket对象
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定IP和端口
server.bind(("127.0.0.1", 8888))
# 3. 开始监听
server.listen(5)
print("服务端已启动,等待连接...")
# 4. 接收客户端连接
conn, addr = server.accept()
print(f"客户端 {addr} 已连接")
# 5. 接收消息
data = conn.recv(1024).decode("utf-8")
print(f"收到消息: {data}")
# 6. 回复消息
conn.send("消息已收到".encode("utf-8"))
# 7. 关闭连接
conn.close()
server.close()
5.3 客户端开发
import socket
# 1. 创建socket对象
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 连接服务端
client.connect(("127.0.0.1", 8888))
# 3. 发送消息
client.send("Hello Server".encode("utf-8"))
# 4. 接收回复
reply = client.recv(1024).decode("utf-8")
print(f"服务端回复: {reply}")
# 5. 关闭连接
client.close()
六、正则表达式
6.1 什么是正则表达式
使用字符串定义规则,去验证字符串是否匹配。常用检索、替换符合规则的文本。
6.2 re模块的三个基础方法
import re s = "hello123world456" # match: 从头开始匹配,匹配第一个 result1 = re.match(r"hello", s) print(result1.group()) # hello # search: 全局搜索,找第一个 result2 = re.search(r"\d+", s) print(result2.group()) # 123 # findall: 全局搜索,找所有 result3 = re.findall(r"\d+", s) print(result3) # ['123', '456']
6.3 元字符匹配规则
单字符匹配
| 字符 | 说明 |
|---|---|
. |
匹配任意1个字符(除换行) |
\d |
匹配数字(0-9) |
\D |
匹配非数字 |
\w |
匹配字母、数字、下划线 |
\W |
匹配非字母、数字、下划线 |
\s |
匹配空白字符 |
\S |
匹配非空白字符 |
[abc] |
匹配a或b或c |
[^abc] |
匹配非a/b/c |
[a-z] |
匹配a到z任意字母 |
数量匹配
| 字符 | 说明 |
|---|---|
* |
匹配0次或多次 |
+ |
匹配1次或多次 |
? |
匹配0次或1次 |
{n} |
匹配恰好n次 |
{n,} |
匹配至少n次 |
{n,m} |
匹配n到m次 |
边界匹配
| 字符 | 说明 |
|---|---|
^ |
匹配字符串开头 |
$ |
匹配字符串结尾 |
\b |
匹配单词边界 |
6.4 正则示例
import re
# 1. 匹配账号:字母数字组成,长度6-10
account = "abc123456"
result = re.match(r"^[0-9a-zA-Z]{6,10}$", account)
print(result is not None) # True
# 2. 匹配QQ号:纯数字,长度5-11,第一位不为0
qq = "12345678"
result = re.match(r"^[1-9][0-9]{4,10}$", qq)
print(result is not None) # True
# 3. 匹配邮箱
email = "test@qq.com"
result = re.match(r"^[\w-]+(\.[\w-]+)*@(qq|163|gmail)(\.[\w-]+)+$", email)
print(result is not None) # True
# 4. 查找所有数字
s = "itheima1 @@python2 !!666 ##itcast3"
numbers = re.findall(r"\d", s)
print(numbers) # ['1', '2', '6', '6', '6', '3']
# 5. 查找所有英文字母
letters = re.findall(r"[a-zA-Z]", s)
print(letters) # ['i', 't', 'h', 'e', 'i', 'm', 'a', 'p', 'y', 't', 'h', 'o', 'n', 'i', 't', 'c', 'a', 's', 't']
6.5 r标记
r标记表示原始字符串,内部转义字符无效,作为普通字符。
# 不使用r:\\ 表示一个反斜杠 path1 = "C:\\Users\\test" print(path1) # C:\Users\test # 使用r:保持原样 path2 = r"C:\Users\test" print(path2) # C:\Users\test
七、递归
7.1 什么是递归
函数自己调用自己的一种特殊编程写法。
注意:
-
必须要有退出条件,否则无限递归
-
注意返回值的传递
7.2 递归示例:遍历文件夹
import os
def find_files(path):
"""递归查找文件夹内所有文件"""
if not os.path.exists(path):
print(f"路径不存在: {path}")
return
files = os.listdir(path)
for file in files:
file_path = os.path.join(path, file)
if os.path.isdir(file_path):
# 是文件夹,递归调用
find_files(file_path)
else:
# 是文件,打印路径
print(file_path)
# 使用示例
find_files("D:/test")
7.3 递归示例:计算阶乘
def factorial(n): """递归计算阶乘""" if n <= 1: return 1 return n * factorial(n - 1) print(factorial(5)) # 120 = 5×4×3×2×1
7.4 递归示例:斐波那契数列
def fibonacci(n): """递归计算斐波那契数""" if n <= 1: return n return fibonacci(n - 1) + fibonacci(n - 2) print(fibonacci(10)) # 55
7.5 os模块常用方法
| 方法 | 说明 |
|---|---|
os.listdir(path) |
列出指定目录下的内容 |
os.path.isdir(path) |
判断是否为文件夹 |
os.path.exists(path) |
判断路径是否存在 |
os.path.join(path1, path2) |
拼接路径 |
八、高阶技巧速查表
| 技巧 | 关键字/模块 | 核心要点 |
|---|---|---|
| 闭包 | 嵌套函数 + nonlocal |
内部函数使用外部变量 |
| 装饰器 | @ 语法糖 |
不修改原函数增加功能 |
| 单例模式 | singleton |
类只有一个实例 |
| 工厂模式 | Factory |
统一入口创建对象 |
| 多线程 | threading |
Thread(target=func).start() |
| Socket服务端 | socket |
bind→listen→accept→recv→send |
| Socket客户端 | socket |
connect→send→recv |
| 正则表达式 | re |
match/search/findall |
| 递归 | 函数自调用 | 必须有退出条件 |
更多推荐

所有评论(0)