目录

一、闭包

1.1 什么是闭包

1.2 nonlocal关键字

1.3 闭包的优缺点

二、装饰器

2.1 什么是装饰器

2.2 语法糖写法(@符号)

2.3 带参数的装饰器

三、设计模式

3.1 单例模式

3.2 工厂模式

四、多线程

4.1 进程与线程

4.2 threading模块

4.3 带参数的多线程

五、网络编程(Socket)

5.1 什么是Socket

5.2 服务端开发

5.3 客户端开发

六、正则表达式

6.1 什么是正则表达式

6.2 re模块的三个基础方法

6.3 元字符匹配规则

单字符匹配

数量匹配

边界匹配

6.4 正则示例

6.5 r标记

七、递归

7.1 什么是递归

7.2 递归示例:遍历文件夹

7.3 递归示例:计算阶乘

7.4 递归示例:斐波那契数列

7.5 os模块常用方法

八、高阶技巧速查表


一、闭包

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
递归 函数自调用 必须有退出条件

更多推荐