← 返回
课程

Python 高级阶段快速复习

首发 2026/05/05 阅读 2 评论 0 更新 2026/05/05

Python 高级阶段快速复习

用途:快速过一遍 PPT 核心内容。重点看:概念一句话、语法模板、易错点、典型代码。


0. 总复习路线

  1. 面向对象基础:类、对象、self、属性、魔法方法。
  2. 面向对象高级:继承、重写、super、封装、多态、抽象类、类属性/类方法/静态方法。
  3. OOP 综合案例:学生管理系统,重点是“类怎么拆、数据怎么存、功能怎么循环”。
  4. 闭包与装饰器:闭包保存外层变量;装饰器在不改原函数的情况下增强功能。
  5. 深浅拷贝:浅拷贝只拷贝外层;深拷贝连嵌套对象也复制。
  6. 网络编程:IP、端口、协议;TCP;socket;服务端/客户端流程。
  7. 进程与线程:多任务、并发/并行、进程资源隔离、线程共享全局变量、互斥锁。
  8. 迭代器、生成器、property、正则:高级语法和字符串匹配。

1. 面向对象基础

1.1 面向过程 vs 面向对象

思维 核心 例子
面向过程 按步骤解决问题 第一步开冰箱,第二步放大象,第三步关冰箱
面向对象 找对象,让对象做事 冰箱对象有“打开/关闭”方法,大象对象被放进去

一句话: 面向对象就是尽量用代码模拟现实世界,把“属性”和“行为”封装到对象中。

1.2 三大特性

特性 大白话 作用
封装 把属性和方法放到类里,对外提供接口 简化使用,提高安全性
继承 子类复用父类的属性和方法 减少重复代码
多态 同一个方法/函数,传入不同对象表现不同 解耦、扩展性强

1.3 类、对象、self

python
class Car(object):
    def run(self):
        print("汽车能跑")

car = Car()      # 创建对象/实例化
car.run()        # 对象调用方法
  • :抽象模板,例如汽车图纸。
  • 对象:具体实体,例如某一辆车。
  • self:指向当前调用方法的对象本身。谁调用方法,self 就是谁。
python
class Car(object):
    def run(self):
        print(self)   # 当前对象

car1 = Car()
car2 = Car()
car1.run()
car2.run()

易错点:

  • 类内部调用自己的属性:self.属性名
  • 类内部调用自己的方法:self.方法名()
  • 类外部调用:对象名.属性名对象名.方法名()

1.4 对象属性

python
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__ 对象被删除/程序结束时 释放资源或观察对象销毁
python
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__():输出地瓜状态

核心代码:

python
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 类的三种写法

python
class Teacher:
    pass

class Teacher():
    pass

class Teacher(object):
    pass

课件建议重点使用:

python
class 类名(object):
    pass

补充理解:Python 3 中默认继承 object,所以 class A:class A(object): 基本等价,但写 object 更利于初学时理解“所有类最终继承 object”。

2.2 继承

python
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 单继承与多继承

python
class Son(Father):
    pass
python
class Son(Father, Mother):
    pass

多继承时,如果多个父类有同名属性或方法,默认按继承顺序查找,先找第一个父类。

python
print(Son.__mro__)
print(Son.mro())

MRO:Method Resolution Order,方法解析顺序。

2.4 重写与调用父类方法

子类定义了和父类同名的方法或属性,就会优先使用子类自己的。

python
class Father(object):
    def make_cake(self):
        print("父类配方")

class Son(Father):
    def make_cake(self):
        print("子类新配方")

子类想调用父类方法:

python
class Son(Father):
    def make_old_cake(self):
        super().make_cake()

也可以写:

python
Father.make_cake(self)

但更推荐 super()

易错点:

  • super().方法名() 不需要手动传 self
  • 父类名.方法名(self) 需要手动传 self
  • 多继承时 super() 会按 MRO 走,复杂多继承要谨慎。

2.5 多层继承

python
class A(object):
    pass

class B(A):
    pass

class C(B):
    pass

C 可以继承 B 的内容,也能间接继承 A 的内容。

2.6 封装与私有属性

私有属性/方法:在名字前加两个下划线 __

python
class Person(object):
    def __init__(self):
        self.__money = 1000

    def get_money(self):
        return self.__money

    def set_money(self, money):
        self.__money = money

私有方法:

python
class Person(object):
    def __secret(self):
        print("私有方法")

    def call_secret(self):
        self.__secret()

记忆: 私有成员不能在类外直接访问,一般通过公有方法间接访问。

2.7 多态

多态:同一个调用方式,传入不同子类对象,产生不同效果。

成立条件按课件记:

  1. 有继承。
  2. 子类重写父类方法。
  3. 父类引用指向子类对象,也就是框架函数接收父类类型,实际传入子类对象。
python
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 抽象类/接口思想

抽象类:父类只规定“必须有什么方法”,具体怎么做交给子类。

python
class Animal(object):
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("汪汪")

一句话: 抽象类像行业标准,子类像不同厂家,各自实现标准。

2.9 类属性、类方法、静态方法

对象属性

每个对象自己一份。

python
class Phone(object):
    def __init__(self):
        self.brand = "华为"

类属性

属于类,被所有对象共享。

python
class Person(object):
    count = 0

print(Person.count)   # 推荐

类方法

python
class Dog(object):
    @classmethod
    def eat(cls):
        print("小狗都喜欢骨头")

Dog.eat()
  • 第一个参数是 cls,代表类本身。
  • 常用于访问/修改类属性。

静态方法

python
class Game(object):
    @staticmethod
    def show_menu():
        print("1.开始 2.暂停 0.退出")

Game.show_menu()
  • 不需要 self,也不需要 cls
  • 只是放在类里的普通工具函数。

3. 学生管理系统综合案例

3.1 项目拆分

推荐文件结构:

python
StudentManagerSystem/
├── main.py          # 程序入口
├── student.py       # 学生类
└── studentcms.py    # 管理系统类

角色:

  1. Student:表示一个学生。
  2. StudentCms:管理学生信息。

3.2 Student 类

python
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 管理系统核心属性

python
class StudentCms(object):
    def __init__(self):
        self.student_list = []   # 列表中存学生对象

3.4 主循环框架

python
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 增删改查思路

添加

python
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)

删除

python
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("学生不存在")

修改

python
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("学生不存在")

查询

python
def query_student(self):
    name = input("请输入要查询的姓名:")
    for student in self.student_list:
        if name in student.name:
            print(student)
            break
    else:
        print("学生不存在")

显示全部

python
def show_all_student(self):
    for student in self.student_list:
        print(student)

3.6 保存与加载

保存对象时不能直接保存对象内存地址,要转成字典。

python
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))

加载:

python
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

python
from studentcms import StudentCms

if __name__ == "__main__":
    cms = StudentCms()
    cms.start()

4. 闭包、装饰器、深浅拷贝

4.1 闭包

闭包作用:保存外部函数中的变量,让它在外部函数执行完后仍然能被内部函数使用。

闭包三条件:

  1. 有函数嵌套。
  2. 内部函数使用外部函数变量。
  3. 外部函数返回内部函数。
python
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

python
def func_out():
    a = 100

    def func_inner():
        nonlocal a
        a += 1
        print(a)

    return func_inner
  • global:声明全局变量。
  • nonlocal:声明外层函数的局部变量。

4.3 装饰器

装饰器作用:不修改原函数代码的前提下,给原函数增加额外功能。

装饰器本质:闭包函数。

python
def check(fn):
    def inner():
        print("登录验证")
        fn()
    return inner

@check
def comment():
    print("发表评论")

comment()

解释器遇到:

python
@check
def comment():
    pass

等价于:

python
comment = check(comment)

4.4 通用装饰器模板

原函数有参数、有返回值时,内部函数也要接收参数并返回结果。

python
def decorator(fn):
    def inner(*args, **kwargs):
        print("额外功能")
        return fn(*args, **kwargs)
    return inner

一句话: 原函数有没有参数、有没有返回值,装饰器内部函数就要对应处理。

4.5 多个装饰器

python
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("发表评论")

装饰过程:离函数最近的先装饰,由内到外。

等价于:

python
comment = check_user(check_code(comment))

调用执行时:外层先执行。

4.6 带参数的装饰器

带参数装饰器 = 外面再包一层函数,用来接收装饰器参数。

python
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

记忆结构:

python
def 外层函数(装饰器参数):
    def 装饰器(原函数):
        def 内层函数(*args, **kwargs):
            return 原函数(*args, **kwargs)
        return 内层函数
    return 装饰器

4.7 浅拷贝与深拷贝

python
import copy

b = copy.copy(a)       # 浅拷贝
c = copy.deepcopy(a)   # 深拷贝
类型 含义 嵌套对象是否独立
赋值 多个变量指向同一个对象 不独立
浅拷贝 只复制最外层对象 内层嵌套对象仍共享
深拷贝 递归复制所有层级 基本独立

例子:

python
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:传输控制协议,特点是面向连接、可靠传输、基于字节流

通信流程:

  1. 建立连接。
  2. 传输数据。
  3. 关闭连接。

三次握手:建立连接。

  1. 客户端请求连接。
  2. 服务端确认收到请求。
  3. 客户端再次确认,连接建立。

四次挥手:断开连接。

  1. A 请求关闭。
  2. B 确认 A 的关闭请求。
  3. B 请求关闭。
  4. A 确认 B 的关闭请求。

5.3 socket

socket 是进程间网络通信的工具。

python
import socket

tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  • AF_INET:IPv4。
  • SOCK_STREAM:TCP。

网络传输的是 bytes,字符串要编码/解码:

python
s = "你好"
b = s.encode("utf-8")
s2 = b.decode("utf-8")

5.4 TCP 服务端流程

  1. 创建 socket。
  2. 绑定 IP 和端口。
  3. 设置监听。
  4. 等待客户端连接。
  5. 接收/发送数据。
  6. 关闭连接 socket。
  7. 关闭服务端 socket。
python
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 客户端流程

  1. 创建 socket。
  2. 连接服务端。
  3. 发送/接收数据。
  4. 关闭 socket。
python
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 的数据。
  • 服务端重启端口没释放,可加:
python
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

6. 进程

6.1 多任务、并发、并行

概念 含义
多任务 同一时间段内执行多个任务,用户感觉像同时运行
并发 单核 CPU 交替执行多个任务
并行 多核 CPU 真正同时执行多个任务

6.2 进程概念

进程是操作系统进行资源分配和调度运行的基本单位,也可理解为“正在运行的程序”。

特点:

  • 一个程序运行后至少有一个主进程。
  • 主进程可以创建子进程。
  • 进程之间默认不共享全局变量。

6.3 创建多进程

python
import multiprocessing

def task():
    print("任务执行")

if __name__ == "__main__":
    p = multiprocessing.Process(target=task)
    p.start()

带参数:

python
def coding(num, name):
    for i in range(num):
        print(f"{name}写第{i}行代码")

p = multiprocessing.Process(target=coding, args=(3, "小明"))
p.start()
python
def music(count, name):
    print(count, name)

p = multiprocessing.Process(target=music, kwargs={"count": 3, "name": "小明"})
p.start()

6.4 进程编号

python
import os
import multiprocessing

print(os.getpid())                         # 当前进程 ID
print(os.getppid())                        # 父进程 ID
print(multiprocessing.current_process().pid)

6.5 进程注意点

进程之间不共享全局变量

python
import multiprocessing

my_list = []

def write_data():
    my_list.append(1)
    print("write:", my_list)

def read_data():
    print("read:", my_list)

子进程会复制主进程资源,名字相同但不是同一块内存。

主进程默认等待子进程结束

python
p = multiprocessing.Process(target=task)
p.start()

主进程结束前,通常会等子进程执行完。

不想等:

python
p.daemon = True   # 主进程结束,子进程跟着销毁
p.start()

或:

python
p.terminate()     # 手动终止子进程,不太推荐

7. 线程

7.1 线程概念

  • 进程是资源分配的基本单位。
  • 线程是 CPU 调度的基本单位。
  • 一个进程至少有一个线程,默认叫主线程。
  • 线程必须依附于进程存在。

7.2 创建多线程

python
import threading

def task():
    print("线程任务")

thread = threading.Thread(target=task)
thread.start()

带参数:

python
threading.Thread(target=coding, args=(3, "小明")).start()
threading.Thread(target=music, kwargs={"count": 3, "name": "小明"}).start()

7.3 线程注意点

  1. 线程执行顺序是无序的,由 CPU 调度决定。
  2. 主线程默认等待所有子线程执行完再结束。
  3. 线程之间共享全局变量。
  4. 共享全局变量可能出现数据安全问题。

守护线程:

python
thread = threading.Thread(target=task, daemon=True)
thread.start()

7.4 线程共享全局变量

python
import threading

my_list = []

def write_data():
    my_list.append(1)

threading.Thread(target=write_data).start()

同一进程内的多个线程共享全局变量,所以一个线程修改后,其他线程能看到。

7.5 数据安全与互斥锁

多个线程同时修改同一个全局变量,可能导致结果错误。

互斥锁:同一时刻只允许一个线程操作共享数据。

python
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()

更安全写法:

python
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__() 的对象。

python
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 生成器

生成器是更简单的迭代器写法。

生成器推导式

python
g = (i * 2 for i in range(5))
for value in g:
    print(value)

注意:小括号里是生成规则,不是一次性存好所有数据。

yield 生成器

python
def my_generator(n):
    for i in range(n):
        print("开始生成")
        yield i
        print("完成一次")

yield 作用:

  1. 返回 yield 后面的值。
  2. 暂停函数执行,下次从暂停位置继续。

for 循环会自动处理 StopIteration,所以比手动 next() 更方便。

8.3 迭代器 vs 生成器

对比 迭代器 生成器
实现方式 手写 __iter____next__ 使用 yield
状态管理 自己管理 Python 自动管理
代码量 较多 简洁
场景 复杂迭代逻辑 简洁生成数据、大数据按需生成

8.4 property 属性

作用:把方法当成属性使用,简化调用,同时可控制读写逻辑。

装饰器方式

python
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

类属性方式

python
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 三步:

python
import re

result = re.match(pattern, string)
if result:
    print(result.group())

8.6 match、search、sub

python
re.match(pattern, string)    # 从字符串开头匹配
re.search(pattern, string)   # 扫描整个字符串,返回第一个匹配
re.sub(pattern, repl, string) # 替换

例子:

python
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 之外的字符
python
re.match(r"^\d.*\d$", "11itcast22")

表示:以数字开头,以数字结尾,中间任意内容。

8.10 分组

python
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

邮箱例子:

python
result = re.match(r"[a-zA-Z0-9_]{4,20}@(163|126|qq)\.com", "hello@qq.com")

分组引用:

python
result = re.match(r"<([a-zA-Z1-6]{1,10})>.*</\1>", "<html>hh</html>")

\1 表示引用第一个分组匹配到的内容,保证前后标签一致。


9. 最后速记清单

9.1 必背语法模板

python
# 类
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 高频易错点

  1. self 不是随便写的,它代表当前对象。
  2. __init__ 创建对象时自动执行,不是手动调用的普通函数。
  3. __str__ 必须 return 字符串,不能直接 print
  4. 子类重写父类方法后,优先调用子类方法。
  5. super().方法() 不写 self
  6. 私有属性 __xxx 类外不能直接访问,应写 get_xxx / set_xxx
  7. 装饰器如果原函数有返回值,内部函数也必须 return
  8. 多个装饰器:装饰时由内到外,执行时由外到内。
  9. 浅拷贝遇到嵌套可变对象,内层仍然共享。
  10. TCP 客户端连接端口必须和服务端绑定端口一致。
  11. 进程不共享全局变量,线程共享全局变量。
  12. 线程共享数据要加锁,加锁后必须释放锁。
  13. re.match() 从开头匹配;想从中间找用 re.search()
  14. 正则里 . 想表示真正的小数点,要写 \. 或使用原始字符串 r"\."

9.3 用一句话串起来

Python 高级这一组课的主线是:先用面向对象把现实事物抽象成类和对象,再用继承、封装、多态提高代码复用和扩展性;遇到函数增强用闭包和装饰器,遇到对象复制要区分浅拷贝和深拷贝;做网络通信要掌握 IP、端口、协议、socket、TCP;做多任务要区分进程和线程;处理大数据遍历用迭代器/生成器;处理字符串规则匹配用正则表达式

相关文章

| 匹配字符串结尾 |\n| `[^abc]` | 匹配除了 a/b/c 之外的字符 |\n\n```python\nre.match(r\"^\\d.*\\d$\", \"11itcast22\")\n```\n\n表示:以数字开头,以数字结尾,中间任意内容。\n\n## 8.10 分组\n\n```python\nresult = re.match(r\"(qq):([1-9]\\d{4,11})\", \"qq:10567\")\n\nprint(result.group()) # 全部:qq:10567\nprint(result.group(1)) # qq\nprint(result.group(2)) # 10567\n```\n\n邮箱例子:\n\n```python\nresult = re.match(r\"[a-zA-Z0-9_]{4,20}@(163|126|qq)\\.com\", \"hello@qq.com\")\n```\n\n分组引用:\n\n```python\nresult = re.match(r\"\u003c([a-zA-Z1-6]{1,10})\u003e.*\u003c/\\1\u003e\", \"\u003chtml\u003ehh\u003c/html\u003e\")\n```\n\n`\\1` 表示引用第一个分组匹配到的内容,保证前后标签一致。\n\n---\n\n# 9. 最后速记清单\n\n## 9.1 必背语法模板\n\n```python\n# 类\nclass 类名(object):\n def __init__(self):\n pass\n\n# 继承\nclass 子类(父类):\n pass\n\n# 调父类\nsuper().方法名()\n\n# 私有属性\nself.__属性名 = 值\n\n# 类方法\n@classmethod\ndef 方法名(cls):\n pass\n\n# 静态方法\n@staticmethod\ndef 方法名():\n pass\n\n# 闭包\ndef outer():\n x = 1\n def inner():\n print(x)\n return inner\n\n# 通用装饰器\ndef decorator(fn):\n def inner(*args, **kwargs):\n return fn(*args, **kwargs)\n return inner\n\n# 进程\nmultiprocessing.Process(target=任务名).start()\n\n# 线程\nthreading.Thread(target=任务名).start()\n\n# socket\nsocket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\n# 正则\nresult = re.match(pattern, string)\nif result:\n result.group()\n```\n\n## 9.2 高频易错点\n\n1. `self` 不是随便写的,它代表当前对象。\n2. `__init__` 创建对象时自动执行,不是手动调用的普通函数。\n3. `__str__` 必须 `return` 字符串,不能直接 `print`。\n4. 子类重写父类方法后,优先调用子类方法。\n5. `super().方法()` 不写 `self`。\n6. 私有属性 `__xxx` 类外不能直接访问,应写 `get_xxx` / `set_xxx`。\n7. 装饰器如果原函数有返回值,内部函数也必须 `return`。\n8. 多个装饰器:装饰时由内到外,执行时由外到内。\n9. 浅拷贝遇到嵌套可变对象,内层仍然共享。\n10. TCP 客户端连接端口必须和服务端绑定端口一致。\n11. 进程不共享全局变量,线程共享全局变量。\n12. 线程共享数据要加锁,加锁后必须释放锁。\n13. `re.match()` 从开头匹配;想从中间找用 `re.search()`。\n14. 正则里 `.` 想表示真正的小数点,要写 `\\.` 或使用原始字符串 `r\"\\.\"`。\n\n## 9.3 用一句话串起来\n\nPython 高级这一组课的主线是:先用**面向对象**把现实事物抽象成类和对象,再用**继承、封装、多态**提高代码复用和扩展性;遇到函数增强用**闭包和装饰器**,遇到对象复制要区分**浅拷贝和深拷贝**;做网络通信要掌握 **IP、端口、协议、socket、TCP**;做多任务要区分**进程和线程**;处理大数据遍历用**迭代器/生成器**;处理字符串规则匹配用**正则表达式**。\n","content_html":"\u003ch1 id=\"python-高级阶段快速复习\"\u003ePython 高级阶段快速复习\u003c/h1\u003e\u003cblockquote\u003e\n\u003cp\u003e用途:快速过一遍 PPT 核心内容。重点看:概念一句话、语法模板、易错点、典型代码。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"0-总复习路线\"\u003e0. 总复习路线\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e面向对象基础\u003c/strong\u003e:类、对象、self、属性、魔法方法。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e面向对象高级\u003c/strong\u003e:继承、重写、super、封装、多态、抽象类、类属性/类方法/静态方法。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOOP 综合案例\u003c/strong\u003e:学生管理系统,重点是“类怎么拆、数据怎么存、功能怎么循环”。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e闭包与装饰器\u003c/strong\u003e:闭包保存外层变量;装饰器在不改原函数的情况下增强功能。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e深浅拷贝\u003c/strong\u003e:浅拷贝只拷贝外层;深拷贝连嵌套对象也复制。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e网络编程\u003c/strong\u003e:IP、端口、协议;TCP;socket;服务端/客户端流程。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e进程与线程\u003c/strong\u003e:多任务、并发/并行、进程资源隔离、线程共享全局变量、互斥锁。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e迭代器、生成器、property、正则\u003c/strong\u003e:高级语法和字符串匹配。\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch1 id=\"1-面向对象基础\"\u003e1. 面向对象基础\u003c/h1\u003e\u003ch2 id=\"1-1-面向过程-vs-面向对象\"\u003e1.1 面向过程 vs 面向对象\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e思维\u003c/th\u003e\n\u003cth\u003e核心\u003c/th\u003e\n\u003cth\u003e例子\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e面向过程\u003c/td\u003e\n\u003ctd\u003e按步骤解决问题\u003c/td\u003e\n\u003ctd\u003e第一步开冰箱,第二步放大象,第三步关冰箱\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e面向对象\u003c/td\u003e\n\u003ctd\u003e找对象,让对象做事\u003c/td\u003e\n\u003ctd\u003e冰箱对象有“打开/关闭”方法,大象对象被放进去\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003e一句话:\u003c/strong\u003e 面向对象就是尽量用代码模拟现实世界,把“属性”和“行为”封装到对象中。\u003c/p\u003e\n\u003ch2 id=\"1-2-三大特性\"\u003e1.2 三大特性\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e特性\u003c/th\u003e\n\u003cth\u003e大白话\u003c/th\u003e\n\u003cth\u003e作用\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e封装\u003c/td\u003e\n\u003ctd\u003e把属性和方法放到类里,对外提供接口\u003c/td\u003e\n\u003ctd\u003e简化使用,提高安全性\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e继承\u003c/td\u003e\n\u003ctd\u003e子类复用父类的属性和方法\u003c/td\u003e\n\u003ctd\u003e减少重复代码\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e多态\u003c/td\u003e\n\u003ctd\u003e同一个方法/函数,传入不同对象表现不同\u003c/td\u003e\n\u003ctd\u003e解耦、扩展性强\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"1-3-类-对象-self\"\u003e1.3 类、对象、self\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20run(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E6%B1%BD%E8%BD%A6%E8%83%BD%E8%B7%91%22)%0A%0Acar%20%3D%20Car()%20%20%20%20%20%20%23%20%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%2F%E5%AE%9E%E4%BE%8B%E5%8C%96%0Acar.run()%20%20%20%20%20%20%20%20%23%20%E5%AF%B9%E8%B1%A1%E8%B0%83%E7%94%A8%E6%96%B9%E6%B3%95\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003erun\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"汽车能跑\"\u003c/span\u003e)\n\ncar = Car() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 创建对象/实例化\u003c/span\u003e\ncar.run() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 对象调用方法\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e类\u003c/strong\u003e:抽象模板,例如汽车图纸。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e对象\u003c/strong\u003e:具体实体,例如某一辆车。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eself\u003c/strong\u003e:指向当前调用方法的对象本身。谁调用方法,\u003ccode\u003eself\u003c/code\u003e 就是谁。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20run(self)%3A%0A%20%20%20%20%20%20%20%20print(self)%20%20%20%23%20%E5%BD%93%E5%89%8D%E5%AF%B9%E8%B1%A1%0A%0Acar1%20%3D%20Car()%0Acar2%20%3D%20Car()%0Acar1.run()%0Acar2.run()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003erun\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 当前对象\u003c/span\u003e\n\ncar1 = Car()\ncar2 = Car()\ncar1.run()\ncar2.run()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e类内部调用自己的属性:\u003ccode\u003eself.属性名\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e类内部调用自己的方法:\u003ccode\u003eself.方法名()\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e类外部调用:\u003ccode\u003e对象名.属性名\u003c/code\u003e、\u003ccode\u003e对象名.方法名()\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"1-4-对象属性\"\u003e1.4 对象属性\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20show(self)%3A%0A%20%20%20%20%20%20%20%20print(self.color)%0A%20%20%20%20%20%20%20%20print(self.number)%0A%0Acar%20%3D%20Car()%0Acar.color%20%3D%20%22%E7%BA%A2%E8%89%B2%22%20%20%20%20%20%20%23%20%E7%B1%BB%E5%A4%96%E9%83%A8%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%0Acar.number%20%3D%204%0Acar.show()%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E7%B1%BB%E5%86%85%E9%83%A8%E9%80%9A%E8%BF%87%20self%20%E8%AE%BF%E9%97%AE\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eshow\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.color)\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.number)\n\ncar = Car()\ncar.color = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"红色\"\u003c/span\u003e \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类外部添加属性\u003c/span\u003e\ncar.number = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e\ncar.show() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类内部通过 self 访问\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e一般更推荐在 \u003ccode\u003e__init__\u003c/code\u003e 中统一初始化属性,而不是随用随加。\u003c/p\u003e\n\u003ch2 id=\"1-5-魔法方法\"\u003e1.5 魔法方法\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e方法\u003c/th\u003e\n\u003cth\u003e什么时候自动调用\u003c/th\u003e\n\u003cth\u003e作用\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e__init__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e创建对象时\u003c/td\u003e\n\u003ctd\u003e初始化属性\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e__str__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eprint(对象)\u003c/code\u003e 时\u003c/td\u003e\n\u003ctd\u003e返回对象的字符串描述\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e__del__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e对象被删除/程序结束时\u003c/td\u003e\n\u003ctd\u003e释放资源或观察对象销毁\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20__init__(self%2C%20color%2C%20number)%3A%0A%20%20%20%20%20%20%20%20self.color%20%3D%20color%0A%20%20%20%20%20%20%20%20self.number%20%3D%20number%0A%0A%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20return%20f%22%E9%A2%9C%E8%89%B2%EF%BC%9A%7Bself.color%7D%EF%BC%8C%E8%BD%AE%E8%83%8E%E6%95%B0%EF%BC%9A%7Bself.number%7D%22%0A%0A%20%20%20%20def%20__del__(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AF%B9%E8%B1%A1%E8%A2%AB%E5%88%A0%E9%99%A4%22)%0A%0Acar%20%3D%20Car(%22Red%22%2C%204)%0Aprint(car)%0Adel%20car\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, color, number\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.color = color\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.number = number\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__str__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"颜色:\u003cspan class=\"hljs-subst\"\u003e{self.color}\u003c/span\u003e,轮胎数:\u003cspan class=\"hljs-subst\"\u003e{self.number}\u003c/span\u003e\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__del__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"对象被删除\"\u003c/span\u003e)\n\ncar = Car(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"Red\"\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(car)\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edel\u003c/span\u003e car\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e记忆:\u003c/strong\u003e \u003ccode\u003e__init__\u003c/code\u003e 管出生,\u003ccode\u003e__str__\u003c/code\u003e 管打印,\u003ccode\u003e__del__\u003c/code\u003e 管销毁。\u003c/p\u003e\n\u003ch2 id=\"1-6-综合小案例思路-烤地瓜\"\u003e1.6 综合小案例思路:烤地瓜\u003c/h2\u003e\u003cp\u003e对象:地瓜。\u003c/p\u003e\n\u003cp\u003e属性:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ecook_time\u003c/code\u003e:总共烤了多久\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecook_state\u003c/code\u003e:当前状态\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003econdiments\u003c/code\u003e:调料列表\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e方法:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ecook(time)\u003c/code\u003e:累计时间,并根据总时间更新状态\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eadd_condiments(condiment)\u003c/code\u003e:添加调料\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e__str__()\u003c/code\u003e:输出地瓜状态\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e核心代码:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20SweetPotato(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.cook_time%20%3D%200%0A%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%94%9F%E7%9A%84%22%0A%20%20%20%20%20%20%20%20self.condiments%20%3D%20%5B%5D%0A%0A%20%20%20%20def%20cook(self%2C%20time)%3A%0A%20%20%20%20%20%20%20%20self.cook_time%20%2B%3D%20time%0A%20%20%20%20%20%20%20%20if%20self.cook_time%20%3C%203%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%94%9F%E7%9A%84%22%0A%20%20%20%20%20%20%20%20elif%20self.cook_time%20%3C%205%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E5%8D%8A%E7%94%9F%E4%B8%8D%E7%86%9F%22%0A%20%20%20%20%20%20%20%20elif%20self.cook_time%20%3C%208%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%86%9F%E4%BA%86%22%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%83%A4%E7%B3%8A%E4%BA%86%22%0A%0A%20%20%20%20def%20add_condiments(self%2C%20condiment)%3A%0A%20%20%20%20%20%20%20%20self.condiments.append(condiment)%0A%0A%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20return%20f%22%E6%97%B6%E9%97%B4%EF%BC%9A%7Bself.cook_time%7D%EF%BC%8C%E7%8A%B6%E6%80%81%EF%BC%9A%7Bself.cook_state%7D%EF%BC%8C%E8%B0%83%E6%96%99%EF%BC%9A%7Bself.condiments%7D%22\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSweetPotato\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"生的\"\u003c/span\u003e\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.condiments = []\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecook\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, time\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time += time\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time \u0026lt; \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"生的\"\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time \u0026lt; \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"半生不熟\"\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time \u0026lt; \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e8\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"熟了\"\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"烤糊了\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_condiments\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, condiment\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.condiments.append(condiment)\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__str__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"时间:\u003cspan class=\"hljs-subst\"\u003e{self.cook_time}\u003c/span\u003e,状态:\u003cspan class=\"hljs-subst\"\u003e{self.cook_state}\u003c/span\u003e,调料:\u003cspan class=\"hljs-subst\"\u003e{self.condiments}\u003c/span\u003e\"\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"2-面向对象高级\"\u003e2. 面向对象高级\u003c/h1\u003e\u003ch2 id=\"2-1-类的三种写法\"\u003e2.1 类的三种写法\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Teacher%3A%0A%20%20%20%20pass%0A%0Aclass%20Teacher()%3A%0A%20%20%20%20pass%0A%0Aclass%20Teacher(object)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eTeacher\u003c/span\u003e:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eTeacher\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eTeacher\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e课件建议重点使用:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20%E7%B1%BB%E5%90%8D(object)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003e类名\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e补充理解:Python 3 中默认继承 \u003ccode\u003eobject\u003c/code\u003e,所以 \u003ccode\u003eclass A:\u003c/code\u003e 和 \u003ccode\u003eclass A(object):\u003c/code\u003e 基本等价,但写 \u003ccode\u003eobject\u003c/code\u003e 更利于初学时理解“所有类最终继承 object”。\u003c/p\u003e\n\u003ch2 id=\"2-2-继承\"\u003e2.2 继承\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Father(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.sex%20%3D%20%22%E7%94%B7%22%0A%0A%20%20%20%20def%20walk(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E6%95%A3%E6%AD%A5%22)%0A%0Aclass%20Son(Father)%3A%0A%20%20%20%20pass%0A%0Ason%20%3D%20Son()%0Aprint(son.sex)%0Ason.walk()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.sex = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"男\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ewalk\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"散步\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\nson = Son()\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(son.sex)\nson.walk()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e父类/基类\u003c/strong\u003e:被继承的类。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e子类/派生类\u003c/strong\u003e:继承别人的类。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e作用\u003c/strong\u003e:复用代码,减少重复。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e本质\u003c/strong\u003e:子类对象可以使用父类的属性和方法。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-3-单继承与多继承\"\u003e2.3 单继承与多继承\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Son(Father)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Son(Father%2C%20Mother)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(Father, Mother):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e多继承时,如果多个父类有同名属性或方法,默认按继承顺序查找,先找第一个父类。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"print(Son.__mro__)%0Aprint(Son.mro())\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(Son.__mro__)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(Son.mro())\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003eMRO\u003c/code\u003e:Method Resolution Order,方法解析顺序。\u003c/p\u003e\n\u003ch2 id=\"2-4-重写与调用父类方法\"\u003e2.4 重写与调用父类方法\u003c/h2\u003e\u003cp\u003e子类定义了和父类同名的方法或属性,就会优先使用子类自己的。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Father(object)%3A%0A%20%20%20%20def%20make_cake(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%88%B6%E7%B1%BB%E9%85%8D%E6%96%B9%22)%0A%0Aclass%20Son(Father)%3A%0A%20%20%20%20def%20make_cake(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%90%E7%B1%BB%E6%96%B0%E9%85%8D%E6%96%B9%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emake_cake\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"父类配方\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emake_cake\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"子类新配方\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e子类想调用父类方法:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Son(Father)%3A%0A%20%20%20%20def%20make_old_cake(self)%3A%0A%20%20%20%20%20%20%20%20super().make_cake()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emake_old_cake\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003esuper\u003c/span\u003e().make_cake()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e也可以写:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"Father.make_cake(self)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eFather.make_cake(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e但更推荐 \u003ccode\u003esuper()\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003esuper().方法名()\u003c/code\u003e 不需要手动传 \u003ccode\u003eself\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e父类名.方法名(self)\u003c/code\u003e 需要手动传 \u003ccode\u003eself\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e多继承时 \u003ccode\u003esuper()\u003c/code\u003e 会按 MRO 走,复杂多继承要谨慎。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-5-多层继承\"\u003e2.5 多层继承\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20A(object)%3A%0A%20%20%20%20pass%0A%0Aclass%20B(A)%3A%0A%20%20%20%20pass%0A%0Aclass%20C(B)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eA\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eB\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eA\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eC\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eB\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003eC\u003c/code\u003e 可以继承 \u003ccode\u003eB\u003c/code\u003e 的内容,也能间接继承 \u003ccode\u003eA\u003c/code\u003e 的内容。\u003c/p\u003e\n\u003ch2 id=\"2-6-封装与私有属性\"\u003e2.6 封装与私有属性\u003c/h2\u003e\u003cp\u003e私有属性/方法:在名字前加两个下划线 \u003ccode\u003e__\u003c/code\u003e。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.__money%20%3D%201000%0A%0A%20%20%20%20def%20get_money(self)%3A%0A%20%20%20%20%20%20%20%20return%20self.__money%0A%0A%20%20%20%20def%20set_money(self%2C%20money)%3A%0A%20%20%20%20%20%20%20%20self.__money%20%3D%20money\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__money = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1000\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eget_money\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__money\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eset_money\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, money\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__money = money\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e私有方法:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__secret(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%A7%81%E6%9C%89%E6%96%B9%E6%B3%95%22)%0A%0A%20%20%20%20def%20call_secret(self)%3A%0A%20%20%20%20%20%20%20%20self.__secret()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__secret\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"私有方法\"\u003c/span\u003e)\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecall_secret\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__secret()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e记忆:\u003c/strong\u003e 私有成员不能在类外直接访问,一般通过公有方法间接访问。\u003c/p\u003e\n\u003ch2 id=\"2-7-多态\"\u003e2.7 多态\u003c/h2\u003e\u003cp\u003e多态:同一个调用方式,传入不同子类对象,产生不同效果。\u003c/p\u003e\n\u003cp\u003e成立条件按课件记:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e有继承。\u003c/li\u003e\n\u003cli\u003e子类重写父类方法。\u003c/li\u003e\n\u003cli\u003e父类引用指向子类对象,也就是框架函数接收父类类型,实际传入子类对象。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20HeroFighter(object)%3A%0A%20%20%20%20def%20power(self)%3A%0A%20%20%20%20%20%20%20%20return%2060%0A%0Aclass%20AdvHeroFighter(HeroFighter)%3A%0A%20%20%20%20def%20power(self)%3A%0A%20%20%20%20%20%20%20%20return%2080%0A%0Aclass%20EnemyFighter(object)%3A%0A%20%20%20%20def%20attack(self)%3A%0A%20%20%20%20%20%20%20%20return%2070%0A%0Adef%20object_play(hero%3A%20HeroFighter%2C%20enemy%3A%20EnemyFighter)%3A%0A%20%20%20%20if%20hero.power()%20%3E%20enemy.attack()%3A%0A%20%20%20%20%20%20%20%20print(%22%E8%8B%B1%E9%9B%84%E8%83%9C%E5%88%A9%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E8%8B%B1%E9%9B%84%E5%A4%B1%E8%B4%A5%22)%0A%0Aobject_play(HeroFighter()%2C%20EnemyFighter())%0Aobject_play(AdvHeroFighter()%2C%20EnemyFighter())\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eHeroFighter\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003epower\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e60\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eAdvHeroFighter\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eHeroFighter\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003epower\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e80\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eEnemyFighter\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eattack\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e70\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eobject_play\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ehero: HeroFighter, enemy: EnemyFighter\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e hero.power() \u0026gt; enemy.attack():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"英雄胜利\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"英雄失败\"\u003c/span\u003e)\n\nobject_play(HeroFighter(), EnemyFighter())\nobject_play(AdvHeroFighter(), EnemyFighter())\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e好处:\u003c/strong\u003e 平台函数 \u003ccode\u003eobject_play\u003c/code\u003e 不需要改,后来新增更强的战机类也能接入,这就是解耦和扩展。\u003c/p\u003e\n\u003ch2 id=\"2-8-抽象类-接口思想\"\u003e2.8 抽象类/接口思想\u003c/h2\u003e\u003cp\u003e抽象类:父类只规定“必须有什么方法”,具体怎么做交给子类。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Animal(object)%3A%0A%20%20%20%20def%20speak(self)%3A%0A%20%20%20%20%20%20%20%20pass%0A%0Aclass%20Dog(Animal)%3A%0A%20%20%20%20def%20speak(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E6%B1%AA%E6%B1%AA%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eAnimal\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003espeak\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eDog\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eAnimal\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003espeak\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"汪汪\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e一句话:\u003c/strong\u003e 抽象类像行业标准,子类像不同厂家,各自实现标准。\u003c/p\u003e\n\u003ch2 id=\"2-9-类属性-类方法-静态方法\"\u003e2.9 类属性、类方法、静态方法\u003c/h2\u003e\u003ch3 id=\"对象属性\"\u003e对象属性\u003c/h3\u003e\u003cp\u003e每个对象自己一份。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Phone(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.brand%20%3D%20%22%E5%8D%8E%E4%B8%BA%22\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePhone\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.brand = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"华为\"\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"类属性\"\u003e类属性\u003c/h3\u003e\u003cp\u003e属于类,被所有对象共享。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20count%20%3D%200%0A%0Aprint(Person.count)%20%20%20%23%20%E6%8E%A8%E8%8D%90\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n count = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(Person.count) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 推荐\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"类方法\"\u003e类方法\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Dog(object)%3A%0A%20%20%20%20%40classmethod%0A%20%20%20%20def%20eat(cls)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%B0%8F%E7%8B%97%E9%83%BD%E5%96%9C%E6%AC%A2%E9%AA%A8%E5%A4%B4%22)%0A%0ADog.eat()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eDog\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @classmethod\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eeat\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ecls\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小狗都喜欢骨头\"\u003c/span\u003e)\n\nDog.eat()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e第一个参数是 \u003ccode\u003ecls\u003c/code\u003e,代表类本身。\u003c/li\u003e\n\u003cli\u003e常用于访问/修改类属性。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"静态方法\"\u003e静态方法\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Game(object)%3A%0A%20%20%20%20%40staticmethod%0A%20%20%20%20def%20show_menu()%3A%0A%20%20%20%20%20%20%20%20print(%221.%E5%BC%80%E5%A7%8B%202.%E6%9A%82%E5%81%9C%200.%E9%80%80%E5%87%BA%22)%0A%0AGame.show_menu()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eGame\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @staticmethod\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eshow_menu\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"1.开始 2.暂停 0.退出\"\u003c/span\u003e)\n\nGame.show_menu()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e不需要 \u003ccode\u003eself\u003c/code\u003e,也不需要 \u003ccode\u003ecls\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e只是放在类里的普通工具函数。\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch1 id=\"3-学生管理系统综合案例\"\u003e3. 学生管理系统综合案例\u003c/h1\u003e\u003ch2 id=\"3-1-项目拆分\"\u003e3.1 项目拆分\u003c/h2\u003e\u003cp\u003e推荐文件结构:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003etext\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"StudentManagerSystem%2F%0A%E2%94%9C%E2%94%80%E2%94%80%20main.py%20%20%20%20%20%20%20%20%20%20%23%20%E7%A8%8B%E5%BA%8F%E5%85%A5%E5%8F%A3%0A%E2%94%9C%E2%94%80%E2%94%80%20student.py%20%20%20%20%20%20%20%23%20%E5%AD%A6%E7%94%9F%E7%B1%BB%0A%E2%94%94%E2%94%80%E2%94%80%20studentcms.py%20%20%20%20%23%20%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%E7%B1%BB\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003etext\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"StudentManagerSystem%2F%0A%E2%94%9C%E2%94%80%E2%94%80%20main.py%20%20%20%20%20%20%20%20%20%20%23%20%E7%A8%8B%E5%BA%8F%E5%85%A5%E5%8F%A3%0A%E2%94%9C%E2%94%80%E2%94%80%20student.py%20%20%20%20%20%20%20%23%20%E5%AD%A6%E7%94%9F%E7%B1%BB%0A%E2%94%94%E2%94%80%E2%94%80%20studentcms.py%20%20%20%20%23%20%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%E7%B1%BB\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-text\"\u003eStudentManagerSystem/\n├── main.py # 程序入口\n├── student.py # 学生类\n└── studentcms.py # 管理系统类\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\n \u003c/div\u003e\u003cp\u003e角色:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003eStudent\u003c/code\u003e:表示一个学生。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eStudentCms\u003c/code\u003e:管理学生信息。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"3-2-student-类\"\u003e3.2 Student 类\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Student(object)%3A%0A%20%20%20%20def%20__init__(self%2C%20name%2C%20age%2C%20gender%2C%20mobile%2C%20description)%3A%0A%20%20%20%20%20%20%20%20self.name%20%3D%20name%0A%20%20%20%20%20%20%20%20self.age%20%3D%20age%0A%20%20%20%20%20%20%20%20self.gender%20%3D%20gender%0A%20%20%20%20%20%20%20%20self.mobile%20%3D%20mobile%0A%20%20%20%20%20%20%20%20self.description%20%3D%20description%0A%0A%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20return%20f%22%7Bself.name%7D%2C%20%7Bself.age%7D%2C%20%7Bself.gender%7D%2C%20%7Bself.mobile%7D%2C%20%7Bself.description%7D%22\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eStudent\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, name, age, gender, mobile, description\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.name = name\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.age = age\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.gender = gender\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.mobile = mobile\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.description = description\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__str__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"\u003cspan class=\"hljs-subst\"\u003e{self.name}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.age}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.gender}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.mobile}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.description}\u003c/span\u003e\"\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-3-管理系统核心属性\"\u003e3.3 管理系统核心属性\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20StudentCms(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.student_list%20%3D%20%5B%5D%20%20%20%23%20%E5%88%97%E8%A1%A8%E4%B8%AD%E5%AD%98%E5%AD%A6%E7%94%9F%E5%AF%B9%E8%B1%A1\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eStudentCms\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list = [] \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 列表中存学生对象\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-4-主循环框架\"\u003e3.4 主循环框架\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20start(self)%3A%0A%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20self.show_operate_view()%0A%20%20%20%20%20%20%20%20number%20%3D%20int(input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E6%93%8D%E4%BD%9C%E5%BA%8F%E5%8F%B7%EF%BC%9A%22))%0A%0A%20%20%20%20%20%20%20%20if%20number%20%3D%3D%201%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.add_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%202%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.update_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%203%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.delete_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%204%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.query_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%205%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.show_all_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%206%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.save_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E5%BA%8F%E5%8F%B7%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003estart\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewhile\u003c/span\u003e \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.show_operate_view()\n number = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eint\u003c/span\u003e(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入操作序号:\"\u003c/span\u003e))\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.add_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.update_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.delete_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.query_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.show_all_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e6\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.save_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"序号不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-5-增删改查思路\"\u003e3.5 增删改查思路\u003c/h2\u003e\u003ch3 id=\"添加\"\u003e添加\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20add_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20age%20%3D%20int(input(%22%E5%B9%B4%E9%BE%84%EF%BC%9A%22))%0A%20%20%20%20gender%20%3D%20input(%22%E6%80%A7%E5%88%AB%EF%BC%9A%22)%0A%20%20%20%20mobile%20%3D%20input(%22%E8%81%94%E7%B3%BB%E6%96%B9%E5%BC%8F%EF%BC%9A%22)%0A%20%20%20%20description%20%3D%20input(%22%E7%AE%80%E4%BB%8B%EF%BC%9A%22)%0A%0A%20%20%20%20student%20%3D%20Student(name%2C%20age%2C%20gender%2C%20mobile%2C%20description)%0A%20%20%20%20self.student_list.append(student)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"姓名:\"\u003c/span\u003e)\n age = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eint\u003c/span\u003e(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"年龄:\"\u003c/span\u003e))\n gender = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"性别:\"\u003c/span\u003e)\n mobile = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"联系方式:\"\u003c/span\u003e)\n description = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"简介:\"\u003c/span\u003e)\n\n student = Student(name, age, gender, mobile, description)\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list.append(student)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"删除\"\u003e删除\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20delete_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E8%A6%81%E5%88%A0%E9%99%A4%E7%9A%84%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20if%20student.name%20%3D%3D%20name%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.student_list.remove(student)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E5%88%A0%E9%99%A4%E6%88%90%E5%8A%9F%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%A6%E7%94%9F%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edelete_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入要删除的姓名:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e student.name == name:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list.remove(student)\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"删除成功\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"学生不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"修改\"\u003e修改\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20update_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E8%A6%81%E4%BF%AE%E6%94%B9%E7%9A%84%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20if%20student.name%20%3D%3D%20name%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20student.age%20%3D%20int(input(%22%E6%96%B0%E5%B9%B4%E9%BE%84%EF%BC%9A%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20student.gender%20%3D%20input(%22%E6%96%B0%E6%80%A7%E5%88%AB%EF%BC%9A%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20student.mobile%20%3D%20input(%22%E6%96%B0%E8%81%94%E7%B3%BB%E6%96%B9%E5%BC%8F%EF%BC%9A%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20student.description%20%3D%20input(%22%E6%96%B0%E7%AE%80%E4%BB%8B%EF%BC%9A%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%A6%E7%94%9F%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eupdate_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入要修改的姓名:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e student.name == name:\n student.age = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eint\u003c/span\u003e(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新年龄:\"\u003c/span\u003e))\n student.gender = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新性别:\"\u003c/span\u003e)\n student.mobile = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新联系方式:\"\u003c/span\u003e)\n student.description = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新简介:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"学生不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"查询\"\u003e查询\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20query_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E8%A6%81%E6%9F%A5%E8%AF%A2%E7%9A%84%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20if%20name%20in%20student.name%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(student)%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%A6%E7%94%9F%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003equery_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入要查询的姓名:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e name \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e student.name:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(student)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"学生不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"显示全部\"\u003e显示全部\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20show_all_student(self)%3A%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20print(student)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eshow_all_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(student)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-6-保存与加载\"\u003e3.6 保存与加载\u003c/h2\u003e\u003cp\u003e保存对象时不能直接保存对象内存地址,要转成字典。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20save_student(self)%3A%0A%20%20%20%20with%20open(%22student.data%22%2C%20%22w%22%2C%20encoding%3D%22utf-8%22)%20as%20f%3A%0A%20%20%20%20%20%20%20%20data%20%3D%20%5Bstudent.__dict__%20for%20student%20in%20self.student_list%5D%0A%20%20%20%20%20%20%20%20f.write(str(data))\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003esave_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewith\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eopen\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"student.data\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"w\"\u003c/span\u003e, encoding=\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e) \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eas\u003c/span\u003e f:\n data = [student.__dict__ \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list]\n f.write(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003estr\u003c/span\u003e(data))\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e加载:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20load_student(self)%3A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20with%20open(%22student.data%22%2C%20%22r%22%2C%20encoding%3D%22utf-8%22)%20as%20f%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20content%20%3D%20f.read()%0A%20%20%20%20except%20FileNotFoundError%3A%0A%20%20%20%20%20%20%20%20content%20%3D%20%22%5B%5D%22%0A%0A%20%20%20%20if%20not%20content%3A%0A%20%20%20%20%20%20%20%20content%20%3D%20%22%5B%5D%22%0A%0A%20%20%20%20data_list%20%3D%20eval(content)%0A%20%20%20%20self.student_list%20%3D%20%5B%0A%20%20%20%20%20%20%20%20Student(d%5B%22name%22%5D%2C%20d%5B%22age%22%5D%2C%20d%5B%22gender%22%5D%2C%20d%5B%22mobile%22%5D%2C%20d%5B%22description%22%5D)%0A%20%20%20%20%20%20%20%20for%20d%20in%20data_list%0A%20%20%20%20%5D\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eload_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003etry\u003c/span\u003e:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewith\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eopen\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"student.data\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"r\"\u003c/span\u003e, encoding=\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e) \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eas\u003c/span\u003e f:\n content = f.read()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eexcept\u003c/span\u003e FileNotFoundError:\n content = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"[]\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003enot\u003c/span\u003e content:\n content = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"[]\"\u003c/span\u003e\n\n data_list = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eeval\u003c/span\u003e(content)\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list = [\n Student(d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"name\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"age\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"gender\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"mobile\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"description\"\u003c/span\u003e])\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e d \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e data_list\n ]\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课件中有的地方用了 \u003ccode\u003estudent_datas\u003c/code\u003e,有的地方用了 \u003ccode\u003estudent_list\u003c/code\u003e,实际写代码时必须统一变量名。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eeval()\u003c/code\u003e 学习案例可以用,真实开发更推荐 \u003ccode\u003ejson\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003efor ... else\u003c/code\u003e:循环没有被 \u003ccode\u003ebreak\u003c/code\u003e 打断,才执行 \u003ccode\u003eelse\u003c/code\u003e。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-7-main-py\"\u003e3.7 main.py\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"from%20studentcms%20import%20StudentCms%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20cms%20%3D%20StudentCms()%0A%20%20%20%20cms.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efrom\u003c/span\u003e studentcms \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e StudentCms\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e __name__ == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"__main__\"\u003c/span\u003e:\n cms = StudentCms()\n cms.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"4-闭包-装饰器-深浅拷贝\"\u003e4. 闭包、装饰器、深浅拷贝\u003c/h1\u003e\u003ch2 id=\"4-1-闭包\"\u003e4.1 闭包\u003c/h2\u003e\u003cp\u003e闭包作用:保存外部函数中的变量,让它在外部函数执行完后仍然能被内部函数使用。\u003c/p\u003e\n\u003cp\u003e闭包三条件:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e有函数嵌套。\u003c/li\u003e\n\u003cli\u003e内部函数使用外部函数变量。\u003c/li\u003e\n\u003cli\u003e外部函数返回内部函数。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20func_out(num1)%3A%0A%20%20%20%20def%20func_inner(num2)%3A%0A%20%20%20%20%20%20%20%20print(num1%20%2B%20num2)%0A%20%20%20%20return%20func_inner%0A%0Af%20%3D%20func_out(10)%0Af(1)%20%20%20%23%2011\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_out\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003enum1\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_inner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003enum2\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(num1 + num2)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e func_inner\n\nf = func_out(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e10\u003c/span\u003e)\nf(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 11\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"4-2-nonlocal\"\u003e4.2 nonlocal\u003c/h2\u003e\u003cp\u003e内部函数要修改外部函数变量时,用 \u003ccode\u003enonlocal\u003c/code\u003e。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20func_out()%3A%0A%20%20%20%20a%20%3D%20100%0A%0A%20%20%20%20def%20func_inner()%3A%0A%20%20%20%20%20%20%20%20nonlocal%20a%0A%20%20%20%20%20%20%20%20a%20%2B%3D%201%0A%20%20%20%20%20%20%20%20print(a)%0A%0A%20%20%20%20return%20func_inner\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_out\u003c/span\u003e():\n a = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e100\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_inner\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003enonlocal\u003c/span\u003e a\n a += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(a)\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e func_inner\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eglobal\u003c/code\u003e:声明全局变量。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enonlocal\u003c/code\u003e:声明外层函数的局部变量。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"4-3-装饰器\"\u003e4.3 装饰器\u003c/h2\u003e\u003cp\u003e装饰器作用:\u003cstrong\u003e不修改原函数代码的前提下,给原函数增加额外功能。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e装饰器本质:闭包函数。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20check(fn)%3A%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%99%BB%E5%BD%95%E9%AA%8C%E8%AF%81%22)%0A%20%20%20%20%20%20%20%20fn()%0A%20%20%20%20return%20inner%0A%0A%40check%0Adef%20comment()%3A%0A%20%20%20%20print(%22%E5%8F%91%E8%A1%A8%E8%AF%84%E8%AE%BA%22)%0A%0Acomment()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003echeck\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"登录验证\"\u003c/span\u003e)\n fn()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecomment\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"发表评论\"\u003c/span\u003e)\n\ncomment()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e解释器遇到:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"%40check%0Adef%20comment()%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecomment\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e等价于:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"comment%20%3D%20check(comment)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"comment%20%3D%20check(comment)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ecomment = check(comment)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\n \u003c/div\u003e\u003ch2 id=\"4-4-通用装饰器模板\"\u003e4.4 通用装饰器模板\u003c/h2\u003e\u003cp\u003e原函数有参数、有返回值时,内部函数也要接收参数并返回结果。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20decorator(fn)%3A%0A%20%20%20%20def%20inner(*args%2C%20**kwargs)%3A%0A%20%20%20%20%20%20%20%20print(%22%E9%A2%9D%E5%A4%96%E5%8A%9F%E8%83%BD%22)%0A%20%20%20%20%20%20%20%20return%20fn(*args%2C%20**kwargs)%0A%20%20%20%20return%20inner\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edecorator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e*args, **kwargs\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"额外功能\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e fn(*args, **kwargs)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e一句话:\u003c/strong\u003e 原函数有没有参数、有没有返回值,装饰器内部函数就要对应处理。\u003c/p\u003e\n\u003ch2 id=\"4-5-多个装饰器\"\u003e4.5 多个装饰器\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20check_user(fn)%3A%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%94%A8%E6%88%B7%E5%90%8D%E5%AF%86%E7%A0%81%E9%AA%8C%E8%AF%81%22)%0A%20%20%20%20%20%20%20%20fn()%0A%20%20%20%20return%20inner%0A%0Adef%20check_code(fn)%3A%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(%22%E9%AA%8C%E8%AF%81%E7%A0%81%E9%AA%8C%E8%AF%81%22)%0A%20%20%20%20%20%20%20%20fn()%0A%20%20%20%20return%20inner%0A%0A%40check_user%0A%40check_code%0Adef%20comment()%3A%0A%20%20%20%20print(%22%E5%8F%91%E8%A1%A8%E8%AF%84%E8%AE%BA%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003echeck_user\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"用户名密码验证\"\u003c/span\u003e)\n fn()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003echeck_code\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"验证码验证\"\u003c/span\u003e)\n fn()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check_user\u003c/span\u003e\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check_code\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecomment\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"发表评论\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e装饰过程:离函数最近的先装饰,由内到外。\u003c/p\u003e\n\u003cp\u003e等价于:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"comment%20%3D%20check_user(check_code(comment))\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"comment%20%3D%20check_user(check_code(comment))\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ecomment = check_user(check_code(comment))\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\n \u003c/div\u003e\u003cp\u003e调用执行时:外层先执行。\u003c/p\u003e\n\u003ch2 id=\"4-6-带参数的装饰器\"\u003e4.6 带参数的装饰器\u003c/h2\u003e\u003cp\u003e带参数装饰器 = 外面再包一层函数,用来接收装饰器参数。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20logging(flag)%3A%0A%20%20%20%20def%20decorator(fn)%3A%0A%20%20%20%20%20%20%20%20def%20inner(a%2C%20b)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20flag%20%3D%3D%20%22%2B%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E6%AD%A3%E5%9C%A8%E5%8A%A0%E6%B3%95%E8%AE%A1%E7%AE%97%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20elif%20flag%20%3D%3D%20%22-%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E6%AD%A3%E5%9C%A8%E5%87%8F%E6%B3%95%E8%AE%A1%E7%AE%97%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(a%2C%20b)%0A%20%20%20%20%20%20%20%20return%20inner%0A%20%20%20%20return%20decorator%0A%0A%40logging(%22%2B%22)%0Adef%20add(a%2C%20b)%3A%0A%20%20%20%20return%20a%20%2B%20b%0A%0A%40logging(%22-%22)%0Adef%20sub(a%2C%20b)%3A%0A%20%20%20%20return%20a%20-%20b\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003elogging\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eflag\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edecorator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ea, b\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e flag == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"+\"\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"正在加法计算\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e flag == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"-\"\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"正在减法计算\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e fn(a, b)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e decorator\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@logging(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"+\"\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ea, b\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e a + b\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@logging(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"-\"\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003esub\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ea, b\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e a - b\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e记忆结构:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20%E5%A4%96%E5%B1%82%E5%87%BD%E6%95%B0(%E8%A3%85%E9%A5%B0%E5%99%A8%E5%8F%82%E6%95%B0)%3A%0A%20%20%20%20def%20%E8%A3%85%E9%A5%B0%E5%99%A8(%E5%8E%9F%E5%87%BD%E6%95%B0)%3A%0A%20%20%20%20%20%20%20%20def%20%E5%86%85%E5%B1%82%E5%87%BD%E6%95%B0(*args%2C%20**kwargs)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%E5%8E%9F%E5%87%BD%E6%95%B0(*args%2C%20**kwargs)%0A%20%20%20%20%20%20%20%20return%20%E5%86%85%E5%B1%82%E5%87%BD%E6%95%B0%0A%20%20%20%20return%20%E8%A3%85%E9%A5%B0%E5%99%A8\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e外层函数\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e装饰器参数\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e装饰器\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e原函数\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e内层函数\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e*args, **kwargs\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e 原函数(*args, **kwargs)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e 内层函数\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e 装饰器\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"4-7-浅拷贝与深拷贝\"\u003e4.7 浅拷贝与深拷贝\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20copy%0A%0Ab%20%3D%20copy.copy(a)%20%20%20%20%20%20%20%23%20%E6%B5%85%E6%8B%B7%E8%B4%9D%0Ac%20%3D%20copy.deepcopy(a)%20%20%20%23%20%E6%B7%B1%E6%8B%B7%E8%B4%9D\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e copy\n\nb = copy.copy(a) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 浅拷贝\u003c/span\u003e\nc = copy.deepcopy(a) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 深拷贝\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e类型\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003cth\u003e嵌套对象是否独立\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e赋值\u003c/td\u003e\n\u003ctd\u003e多个变量指向同一个对象\u003c/td\u003e\n\u003ctd\u003e不独立\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e浅拷贝\u003c/td\u003e\n\u003ctd\u003e只复制最外层对象\u003c/td\u003e\n\u003ctd\u003e内层嵌套对象仍共享\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e深拷贝\u003c/td\u003e\n\u003ctd\u003e递归复制所有层级\u003c/td\u003e\n\u003ctd\u003e基本独立\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e例子:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20copy%0A%0Aa%20%3D%20%5B1%2C%202%2C%20%5B3%2C%204%5D%5D%0Ab%20%3D%20copy.copy(a)%0Ac%20%3D%20copy.deepcopy(a)%0A%0Aa%5B2%5D.append(5)%0Aprint(b)%20%20%23%20%5B1%2C%202%2C%20%5B3%2C%204%2C%205%5D%5D%EF%BC%8C%E5%8F%97%E5%BD%B1%E5%93%8D%0Aprint(c)%20%20%23%20%5B1%2C%202%2C%20%5B3%2C%204%5D%5D%EF%BC%8C%E4%B8%8D%E5%8F%97%E5%BD%B1%E5%93%8D\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e copy\n\na = [\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e, [\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e]]\nb = copy.copy(a)\nc = copy.deepcopy(a)\n\na[\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e].append(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(b) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# [1, 2, [3, 4, 5]],受影响\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(c) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# [1, 2, [3, 4]],不受影响\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e重点:\u003c/strong\u003e 浅拷贝最怕“列表里面还有列表”这种嵌套可变对象。\u003c/p\u003e\n\u003chr\u003e\n\u003ch1 id=\"5-网络编程\"\u003e5. 网络编程\u003c/h1\u003e\u003ch2 id=\"5-1-网络编程三要素\"\u003e5.1 网络编程三要素\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e要素\u003c/th\u003e\n\u003cth\u003e作用\u003c/th\u003e\n\u003cth\u003e类比\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003eIP 地址\u003c/td\u003e\n\u003ctd\u003e找到哪台电脑\u003c/td\u003e\n\u003ctd\u003e家庭地址\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e端口\u003c/td\u003e\n\u003ctd\u003e找到电脑上的哪个程序\u003c/td\u003e\n\u003ctd\u003e门牌/窗口\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e协议\u003c/td\u003e\n\u003ctd\u003e通信规则\u003c/td\u003e\n\u003ctd\u003e双方都能听懂的语言\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e端口号:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e0~1023:知名端口。\u003c/li\u003e\n\u003cli\u003e1024~65535:动态端口,开发程序常用。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"5-2-tcp-协议\"\u003e5.2 TCP 协议\u003c/h2\u003e\u003cp\u003eTCP:传输控制协议,特点是\u003cstrong\u003e面向连接、可靠传输、基于字节流\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e通信流程:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e建立连接。\u003c/li\u003e\n\u003cli\u003e传输数据。\u003c/li\u003e\n\u003cli\u003e关闭连接。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e三次握手:建立连接。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e客户端请求连接。\u003c/li\u003e\n\u003cli\u003e服务端确认收到请求。\u003c/li\u003e\n\u003cli\u003e客户端再次确认,连接建立。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e四次挥手:断开连接。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eA 请求关闭。\u003c/li\u003e\n\u003cli\u003eB 确认 A 的关闭请求。\u003c/li\u003e\n\u003cli\u003eB 请求关闭。\u003c/li\u003e\n\u003cli\u003eA 确认 B 的关闭请求。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"5-3-socket\"\u003e5.3 socket\u003c/h2\u003e\u003cp\u003esocket 是进程间网络通信的工具。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20socket%0A%0Atcp_socket%20%3D%20socket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e socket\n\ntcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eAF_INET\u003c/code\u003e:IPv4。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eSOCK_STREAM\u003c/code\u003e:TCP。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e网络传输的是 \u003ccode\u003ebytes\u003c/code\u003e,字符串要编码/解码:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"s%20%3D%20%22%E4%BD%A0%E5%A5%BD%22%0Ab%20%3D%20s.encode(%22utf-8%22)%0As2%20%3D%20b.decode(%22utf-8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003es = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"你好\"\u003c/span\u003e\nb = s.encode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e)\ns2 = b.decode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"5-4-tcp-服务端流程\"\u003e5.4 TCP 服务端流程\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e创建 socket。\u003c/li\u003e\n\u003cli\u003e绑定 IP 和端口。\u003c/li\u003e\n\u003cli\u003e设置监听。\u003c/li\u003e\n\u003cli\u003e等待客户端连接。\u003c/li\u003e\n\u003cli\u003e接收/发送数据。\u003c/li\u003e\n\u003cli\u003e关闭连接 socket。\u003c/li\u003e\n\u003cli\u003e关闭服务端 socket。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20socket%0A%0Aserver%20%3D%20socket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)%0Aserver.setsockopt(socket.SOL_SOCKET%2C%20socket.SO_REUSEADDR%2C%20True)%0Aserver.bind((%22%22%2C%208888))%0Aserver.listen(128)%0A%0Aconn%2C%20addr%20%3D%20server.accept()%0Aprint(%22%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%9C%B0%E5%9D%80%EF%BC%9A%22%2C%20addr)%0A%0Adata%20%3D%20conn.recv(1024)%0Aprint(data.decode(%22utf-8%22))%0A%0Aconn.send(%22%E6%94%B6%E5%88%B0%22.encode(%22utf-8%22))%0A%0Aconn.close()%0Aserver.close()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e socket\n\nserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e)\nserver.bind((\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"\"\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e8888\u003c/span\u003e))\nserver.listen(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e128\u003c/span\u003e)\n\nconn, addr = server.accept()\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"客户端地址:\"\u003c/span\u003e, addr)\n\ndata = conn.recv(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1024\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(data.decode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\n\nconn.send(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"收到\"\u003c/span\u003e.encode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\n\nconn.close()\nserver.close()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"5-5-tcp-客户端流程\"\u003e5.5 TCP 客户端流程\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e创建 socket。\u003c/li\u003e\n\u003cli\u003e连接服务端。\u003c/li\u003e\n\u003cli\u003e发送/接收数据。\u003c/li\u003e\n\u003cli\u003e关闭 socket。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20socket%0A%0Aclient%20%3D%20socket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)%0Aclient.connect((%22127.0.0.1%22%2C%208888))%0A%0Aclient.send(%22hello%22.encode(%22utf-8%22))%0Adata%20%3D%20client.recv(1024)%0Aprint(data.decode(%22utf-8%22))%0A%0Aclient.close()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e socket\n\nclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nclient.connect((\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"127.0.0.1\"\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e8888\u003c/span\u003e))\n\nclient.send(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"hello\"\u003c/span\u003e.encode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\ndata = client.recv(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1024\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(data.decode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\n\nclient.close()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e客户端连接的端口必须和服务端绑定的端口一致。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eaccept()\u003c/code\u003e 前的服务端 socket 是“被动套接字”,只负责接收连接。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eaccept()\u003c/code\u003e 返回的新 socket 才负责和具体客户端通信。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erecv()\u003c/code\u003e 是阻塞等待;客户端关闭后,服务端 \u003ccode\u003erecv()\u003c/code\u003e 可能返回长度为 0 的数据。\u003c/li\u003e\n\u003cli\u003e服务端重启端口没释放,可加:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"server.setsockopt(socket.SOL_SOCKET%2C%20socket.SO_REUSEADDR%2C%20True)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"6-进程\"\u003e6. 进程\u003c/h1\u003e\u003ch2 id=\"6-1-多任务-并发-并行\"\u003e6.1 多任务、并发、并行\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e概念\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e多任务\u003c/td\u003e\n\u003ctd\u003e同一时间段内执行多个任务,用户感觉像同时运行\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e并发\u003c/td\u003e\n\u003ctd\u003e单核 CPU 交替执行多个任务\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e并行\u003c/td\u003e\n\u003ctd\u003e多核 CPU 真正同时执行多个任务\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"6-2-进程概念\"\u003e6.2 进程概念\u003c/h2\u003e\u003cp\u003e进程是操作系统进行资源分配和调度运行的基本单位,也可理解为“正在运行的程序”。\u003c/p\u003e\n\u003cp\u003e特点:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一个程序运行后至少有一个主进程。\u003c/li\u003e\n\u003cli\u003e主进程可以创建子进程。\u003c/li\u003e\n\u003cli\u003e进程之间默认不共享全局变量。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"6-3-创建多进程\"\u003e6.3 创建多进程\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20multiprocessing%0A%0Adef%20task()%3A%0A%20%20%20%20print(%22%E4%BB%BB%E5%8A%A1%E6%89%A7%E8%A1%8C%22)%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20p%20%3D%20multiprocessing.Process(target%3Dtask)%0A%20%20%20%20p.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e multiprocessing\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003etask\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"任务执行\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e __name__ == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"__main__\"\u003c/span\u003e:\n p = multiprocessing.Process(target=task)\n p.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e带参数:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20coding(num%2C%20name)%3A%0A%20%20%20%20for%20i%20in%20range(num)%3A%0A%20%20%20%20%20%20%20%20print(f%22%7Bname%7D%E5%86%99%E7%AC%AC%7Bi%7D%E8%A1%8C%E4%BB%A3%E7%A0%81%22)%0A%0Ap%20%3D%20multiprocessing.Process(target%3Dcoding%2C%20args%3D(3%2C%20%22%E5%B0%8F%E6%98%8E%22))%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecoding\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003enum, name\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e i \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(num):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"\u003cspan class=\"hljs-subst\"\u003e{name}\u003c/span\u003e写第\u003cspan class=\"hljs-subst\"\u003e{i}\u003c/span\u003e行代码\"\u003c/span\u003e)\n\np = multiprocessing.Process(target=coding, args=(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e))\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20music(count%2C%20name)%3A%0A%20%20%20%20print(count%2C%20name)%0A%0Ap%20%3D%20multiprocessing.Process(target%3Dmusic%2C%20kwargs%3D%7B%22count%22%3A%203%2C%20%22name%22%3A%20%22%E5%B0%8F%E6%98%8E%22%7D)%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emusic\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ecount, name\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(count, name)\n\np = multiprocessing.Process(target=music, kwargs={\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"count\"\u003c/span\u003e: \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"name\"\u003c/span\u003e: \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e})\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"6-4-进程编号\"\u003e6.4 进程编号\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20os%0Aimport%20multiprocessing%0A%0Aprint(os.getpid())%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E5%BD%93%E5%89%8D%E8%BF%9B%E7%A8%8B%20ID%0Aprint(os.getppid())%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E7%88%B6%E8%BF%9B%E7%A8%8B%20ID%0Aprint(multiprocessing.current_process().pid)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e os\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e multiprocessing\n\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(os.getpid()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 当前进程 ID\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(os.getppid()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 父进程 ID\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(multiprocessing.current_process().pid)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"6-5-进程注意点\"\u003e6.5 进程注意点\u003c/h2\u003e\u003ch3 id=\"进程之间不共享全局变量\"\u003e进程之间不共享全局变量\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20multiprocessing%0A%0Amy_list%20%3D%20%5B%5D%0A%0Adef%20write_data()%3A%0A%20%20%20%20my_list.append(1)%0A%20%20%20%20print(%22write%3A%22%2C%20my_list)%0A%0Adef%20read_data()%3A%0A%20%20%20%20print(%22read%3A%22%2C%20my_list)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e multiprocessing\n\nmy_list = []\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ewrite_data\u003c/span\u003e():\n my_list.append(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e)\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"write:\"\u003c/span\u003e, my_list)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eread_data\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"read:\"\u003c/span\u003e, my_list)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e子进程会复制主进程资源,名字相同但不是同一块内存。\u003c/p\u003e\n\u003ch3 id=\"主进程默认等待子进程结束\"\u003e主进程默认等待子进程结束\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"p%20%3D%20multiprocessing.Process(target%3Dtask)%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"p%20%3D%20multiprocessing.Process(target%3Dtask)%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ep = multiprocessing.Process(target=task)\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\n \u003c/div\u003e\u003cp\u003e主进程结束前,通常会等子进程执行完。\u003c/p\u003e\n\u003cp\u003e不想等:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"p.daemon%20%3D%20True%20%20%20%23%20%E4%B8%BB%E8%BF%9B%E7%A8%8B%E7%BB%93%E6%9D%9F%EF%BC%8C%E5%AD%90%E8%BF%9B%E7%A8%8B%E8%B7%9F%E7%9D%80%E9%94%80%E6%AF%81%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ep.daemon = \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 主进程结束,子进程跟着销毁\u003c/span\u003e\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e或:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"p.terminate()%20%20%20%20%20%23%20%E6%89%8B%E5%8A%A8%E7%BB%88%E6%AD%A2%E5%AD%90%E8%BF%9B%E7%A8%8B%EF%BC%8C%E4%B8%8D%E5%A4%AA%E6%8E%A8%E8%8D%90\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ep.terminate() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 手动终止子进程,不太推荐\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"7-线程\"\u003e7. 线程\u003c/h1\u003e\u003ch2 id=\"7-1-线程概念\"\u003e7.1 线程概念\u003c/h2\u003e\u003cul\u003e\n\u003cli\u003e进程是资源分配的基本单位。\u003c/li\u003e\n\u003cli\u003e线程是 CPU 调度的基本单位。\u003c/li\u003e\n\u003cli\u003e一个进程至少有一个线程,默认叫主线程。\u003c/li\u003e\n\u003cli\u003e线程必须依附于进程存在。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"7-2-创建多线程\"\u003e7.2 创建多线程\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20threading%0A%0Adef%20task()%3A%0A%20%20%20%20print(%22%E7%BA%BF%E7%A8%8B%E4%BB%BB%E5%8A%A1%22)%0A%0Athread%20%3D%20threading.Thread(target%3Dtask)%0Athread.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e threading\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003etask\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"线程任务\"\u003c/span\u003e)\n\nthread = threading.Thread(target=task)\nthread.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e带参数:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"threading.Thread(target%3Dcoding%2C%20args%3D(3%2C%20%22%E5%B0%8F%E6%98%8E%22)).start()%0Athreading.Thread(target%3Dmusic%2C%20kwargs%3D%7B%22count%22%3A%203%2C%20%22name%22%3A%20%22%E5%B0%8F%E6%98%8E%22%7D).start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ethreading.Thread(target=coding, args=(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e)).start()\nthreading.Thread(target=music, kwargs={\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"count\"\u003c/span\u003e: \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"name\"\u003c/span\u003e: \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e}).start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"7-3-线程注意点\"\u003e7.3 线程注意点\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e线程执行顺序是无序的,由 CPU 调度决定。\u003c/li\u003e\n\u003cli\u003e主线程默认等待所有子线程执行完再结束。\u003c/li\u003e\n\u003cli\u003e线程之间共享全局变量。\u003c/li\u003e\n\u003cli\u003e共享全局变量可能出现数据安全问题。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e守护线程:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"thread%20%3D%20threading.Thread(target%3Dtask%2C%20daemon%3DTrue)%0Athread.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ethread = threading.Thread(target=task, daemon=\u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e)\nthread.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"7-4-线程共享全局变量\"\u003e7.4 线程共享全局变量\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20threading%0A%0Amy_list%20%3D%20%5B%5D%0A%0Adef%20write_data()%3A%0A%20%20%20%20my_list.append(1)%0A%0Athreading.Thread(target%3Dwrite_data).start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e threading\n\nmy_list = []\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ewrite_data\u003c/span\u003e():\n my_list.append(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e)\n\nthreading.Thread(target=write_data).start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e同一进程内的多个线程共享全局变量,所以一个线程修改后,其他线程能看到。\u003c/p\u003e\n\u003ch2 id=\"7-5-数据安全与互斥锁\"\u003e7.5 数据安全与互斥锁\u003c/h2\u003e\u003cp\u003e多个线程同时修改同一个全局变量,可能导致结果错误。\u003c/p\u003e\n\u003cp\u003e互斥锁:同一时刻只允许一个线程操作共享数据。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20threading%0A%0Ag_num%20%3D%200%0Amutex%20%3D%20threading.Lock()%0A%0Adef%20add_num()%3A%0A%20%20%20%20global%20g_num%0A%20%20%20%20mutex.acquire()%0A%20%20%20%20for%20_%20in%20range(100000)%3A%0A%20%20%20%20%20%20%20%20g_num%20%2B%3D%201%0A%20%20%20%20mutex.release()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e threading\n\ng_num = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\nmutex = threading.Lock()\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_num\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eglobal\u003c/span\u003e g_num\n mutex.acquire()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e _ \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e100000\u003c/span\u003e):\n g_num += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n mutex.release()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e更安全写法:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20add_num()%3A%0A%20%20%20%20global%20g_num%0A%20%20%20%20with%20mutex%3A%0A%20%20%20%20%20%20%20%20for%20_%20in%20range(100000)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20g_num%20%2B%3D%201\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_num\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eglobal\u003c/span\u003e g_num\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewith\u003c/span\u003e mutex:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e _ \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e100000\u003c/span\u003e):\n g_num += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e死锁:线程一直等对方释放锁,程序卡住。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e 上锁后必须释放锁,否则容易死锁。\u003c/p\u003e\n\u003ch2 id=\"7-6-进程-vs-线程\"\u003e7.6 进程 vs 线程\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e对比\u003c/th\u003e\n\u003cth\u003e进程\u003c/th\u003e\n\u003cth\u003e线程\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e单位\u003c/td\u003e\n\u003ctd\u003e资源分配基本单位\u003c/td\u003e\n\u003ctd\u003eCPU 调度基本单位\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e是否独立\u003c/td\u003e\n\u003ctd\u003e独立\u003c/td\u003e\n\u003ctd\u003e依附于进程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e全局变量\u003c/td\u003e\n\u003ctd\u003e默认不共享\u003c/td\u003e\n\u003ctd\u003e共享\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e开销\u003c/td\u003e\n\u003ctd\u003e大\u003c/td\u003e\n\u003ctd\u003e小\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e稳定性\u003c/td\u003e\n\u003ctd\u003e更强,一个进程挂了不一定影响其他进程\u003c/td\u003e\n\u003ctd\u003e一个线程异常可能影响整个进程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e多核利用\u003c/td\u003e\n\u003ctd\u003e可以更好利用多核\u003c/td\u003e\n\u003ctd\u003eCPython 中 CPU 密集型受 GIL 限制\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e按课件记:多进程资源开销大但稳定性强;多线程资源开销小但要注意共享数据安全。\u003c/p\u003e\n\u003chr\u003e\n\u003ch1 id=\"8-迭代器-生成器-property-正则表达式\"\u003e8. 迭代器、生成器、property、正则表达式\u003c/h1\u003e\u003ch2 id=\"8-1-迭代器\"\u003e8.1 迭代器\u003c/h2\u003e\u003cp\u003e迭代器是实现了 \u003ccode\u003e__iter__()\u003c/code\u003e 和 \u003ccode\u003e__next__()\u003c/code\u003e 的对象。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20MyIterator(object)%3A%0A%20%20%20%20def%20__init__(self%2C%20start%2C%20end)%3A%0A%20%20%20%20%20%20%20%20self.current%20%3D%20start%0A%20%20%20%20%20%20%20%20self.end%20%3D%20end%0A%0A%20%20%20%20def%20__iter__(self)%3A%0A%20%20%20%20%20%20%20%20return%20self%0A%0A%20%20%20%20def%20__next__(self)%3A%0A%20%20%20%20%20%20%20%20if%20self.current%20%3E%20self.end%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20raise%20StopIteration%0A%20%20%20%20%20%20%20%20value%20%3D%20self.current%0A%20%20%20%20%20%20%20%20self.current%20%2B%3D%201%0A%20%20%20%20%20%20%20%20return%20value%0A%0Afor%20num%20in%20MyIterator(1%2C%205)%3A%0A%20%20%20%20print(num)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eMyIterator\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, start, end\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current = start\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.end = end\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__iter__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__next__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current \u0026gt; \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.end:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eraise\u003c/span\u003e StopIteration\n value = \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e value\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e num \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e MyIterator(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(num)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e特点:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e手动管理状态。\u003c/li\u003e\n\u003cli\u003e可以用 \u003ccode\u003enext()\u003c/code\u003e 或 \u003ccode\u003efor\u003c/code\u003e 遍历。\u003c/li\u003e\n\u003cli\u003e惰性计算,适合大数据/流式数据。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"8-2-生成器\"\u003e8.2 生成器\u003c/h2\u003e\u003cp\u003e生成器是更简单的迭代器写法。\u003c/p\u003e\n\u003ch3 id=\"生成器推导式\"\u003e生成器推导式\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"g%20%3D%20(i%20*%202%20for%20i%20in%20range(5))%0Afor%20value%20in%20g%3A%0A%20%20%20%20print(value)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eg = (i * \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e i \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e))\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e value \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e g:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(value)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e注意:小括号里是生成规则,不是一次性存好所有数据。\u003c/p\u003e\n\u003ch3 id=\"yield-生成器\"\u003eyield 生成器\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20my_generator(n)%3A%0A%20%20%20%20for%20i%20in%20range(n)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%BC%80%E5%A7%8B%E7%94%9F%E6%88%90%22)%0A%20%20%20%20%20%20%20%20yield%20i%0A%20%20%20%20%20%20%20%20print(%22%E5%AE%8C%E6%88%90%E4%B8%80%E6%AC%A1%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emy_generator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003en\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e i \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(n):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"开始生成\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eyield\u003c/span\u003e i\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"完成一次\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003eyield\u003c/code\u003e 作用:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e返回 \u003ccode\u003eyield\u003c/code\u003e 后面的值。\u003c/li\u003e\n\u003cli\u003e暂停函数执行,下次从暂停位置继续。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003ccode\u003efor\u003c/code\u003e 循环会自动处理 \u003ccode\u003eStopIteration\u003c/code\u003e,所以比手动 \u003ccode\u003enext()\u003c/code\u003e 更方便。\u003c/p\u003e\n\u003ch2 id=\"8-3-迭代器-vs-生成器\"\u003e8.3 迭代器 vs 生成器\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e对比\u003c/th\u003e\n\u003cth\u003e迭代器\u003c/th\u003e\n\u003cth\u003e生成器\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e实现方式\u003c/td\u003e\n\u003ctd\u003e手写 \u003ccode\u003e__iter__\u003c/code\u003e 和 \u003ccode\u003e__next__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e使用 \u003ccode\u003eyield\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e状态管理\u003c/td\u003e\n\u003ctd\u003e自己管理\u003c/td\u003e\n\u003ctd\u003ePython 自动管理\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e代码量\u003c/td\u003e\n\u003ctd\u003e较多\u003c/td\u003e\n\u003ctd\u003e简洁\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e场景\u003c/td\u003e\n\u003ctd\u003e复杂迭代逻辑\u003c/td\u003e\n\u003ctd\u003e简洁生成数据、大数据按需生成\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"8-4-property-属性\"\u003e8.4 property 属性\u003c/h2\u003e\u003cp\u003e作用:把方法当成属性使用,简化调用,同时可控制读写逻辑。\u003c/p\u003e\n\u003ch3 id=\"装饰器方式\"\u003e装饰器方式\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%200%0A%0A%20%20%20%20%40property%0A%20%20%20%20def%20age(self)%3A%0A%20%20%20%20%20%20%20%20return%20self.__age%0A%0A%20%20%20%20%40age.setter%0A%20%20%20%20def%20age(self%2C%20new_age)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%20new_age%0A%0Ap%20%3D%20Person()%0Aprint(p.age)%0Ap.age%20%3D%2018\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @property\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eage\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @age.setter\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eage\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, new_age\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = new_age\n\np = Person()\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(p.age)\np.age = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e18\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"类属性方式\"\u003e类属性方式\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%200%0A%0A%20%20%20%20def%20get_age(self)%3A%0A%20%20%20%20%20%20%20%20return%20self.__age%0A%0A%20%20%20%20def%20set_age(self%2C%20new_age)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%20new_age%0A%0A%20%20%20%20age%20%3D%20property(get_age%2C%20set_age)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eget_age\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eset_age\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, new_age\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = new_age\n\n age = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eproperty\u003c/span\u003e(get_age, set_age)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"8-5-正则表达式与-re-模块\"\u003e8.5 正则表达式与 re 模块\u003c/h2\u003e\u003cp\u003e正则表达式:用特殊符号描述字符串匹配规则。\u003c/p\u003e\n\u003cp\u003e常见作用:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e数据验证:手机号、邮箱、IP。\u003c/li\u003e\n\u003cli\u003e数据检索:爬虫提取内容。\u003c/li\u003e\n\u003cli\u003e数据替换:敏感词过滤。\u003c/li\u003e\n\u003cli\u003e数据隐藏:手机号脱敏。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003ere 三步:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20re%0A%0Aresult%20%3D%20re.match(pattern%2C%20string)%0Aif%20result%3A%0A%20%20%20%20print(result.group())\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e re\n\nresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(pattern, string)\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e result:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group())\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"8-6-match-search-sub\"\u003e8.6 match、search、sub\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"re.match(pattern%2C%20string)%20%20%20%20%23%20%E4%BB%8E%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%BC%80%E5%A4%B4%E5%8C%B9%E9%85%8D%0Are.search(pattern%2C%20string)%20%20%20%23%20%E6%89%AB%E6%8F%8F%E6%95%B4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E8%BF%94%E5%9B%9E%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%8C%B9%E9%85%8D%0Are.sub(pattern%2C%20repl%2C%20string)%20%23%20%E6%9B%BF%E6%8D%A2\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ere.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(pattern, string) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 从字符串开头匹配\u003c/span\u003e\nre.search(pattern, string) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 扫描整个字符串,返回第一个匹配\u003c/span\u003e\nre.sub(pattern, repl, string) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 替换\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e例子:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20re%0A%0Aresult%20%3D%20re.search(r%22%5Cd.*%22%2C%20%22city%3A1beijing2.shanghai%22)%0Aprint(result.group())%20%20%23%201beijing2.shanghai\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e re\n\nresult = re.search(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"\\d.*\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"city:1beijing2.shanghai\"\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 1beijing2.shanghai\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"8-7-单字符匹配\"\u003e8.7 单字符匹配\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e符号\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e.\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e任意一个字符,除了换行符\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e[abc]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配 a/b/c 中任意一个\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e[a-z]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配小写字母\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\d\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e数字,等价于 \u003ccode\u003e[0-9]\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\D\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e非数字\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\s\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e空白字符,空格、tab 等\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\S\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e非空白\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\w\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e字母、数字、下划线、汉字\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\W\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e非 \u003ccode\u003e\\w\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"8-8-多字符匹配\"\u003e8.8 多字符匹配\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e符号\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 0 次或多次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e+\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 1 次或多次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e?\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 0 次或 1 次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e{m}\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 m 次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e{m,n}\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 m 到 n 次\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e \u003ccode\u003e{2,5}\u003c/code\u003e 逗号后不要写空格。\u003c/p\u003e\n\u003ch2 id=\"8-9-开头-结尾-取反\"\u003e8.9 开头、结尾、取反\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e符号\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e^\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配字符串开头\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e$\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配字符串结尾\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e[^abc]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配除了 a/b/c 之外的字符\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"re.match(r%22%5E%5Cd.*%5Cd%24%22%2C%20%2211itcast22%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ere.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"^\\d.*\\d$\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"11itcast22\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e表示:以数字开头,以数字结尾,中间任意内容。\u003c/p\u003e\n\u003ch2 id=\"8-10-分组\"\u003e8.10 分组\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"result%20%3D%20re.match(r%22(qq)%3A(%5B1-9%5D%5Cd%7B4%2C11%7D)%22%2C%20%22qq%3A10567%22)%0A%0Aprint(result.group())%20%20%20%23%20%E5%85%A8%E9%83%A8%EF%BC%9Aqq%3A10567%0Aprint(result.group(1))%20%20%23%20qq%0Aprint(result.group(2))%20%20%23%2010567\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"(qq):([1-9]\\d{4,11})\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"qq:10567\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 全部:qq:10567\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e)) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# qq\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e)) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 10567\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e邮箱例子:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"result%20%3D%20re.match(r%22%5Ba-zA-Z0-9_%5D%7B4%2C20%7D%40(163%7C126%7Cqq)%5C.com%22%2C%20%22hello%40qq.com%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"[a-zA-Z0-9_]{4,20}@(163|126|qq)\\.com\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"hello@qq.com\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e分组引用:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"result%20%3D%20re.match(r%22%3C(%5Ba-zA-Z1-6%5D%7B1%2C10%7D)%3E.*%3C%2F%5C1%3E%22%2C%20%22%3Chtml%3Ehh%3C%2Fhtml%3E%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"\u0026lt;([a-zA-Z1-6]{1,10})\u0026gt;.*\u0026lt;/\\1\u0026gt;\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"\u0026lt;html\u0026gt;hh\u0026lt;/html\u0026gt;\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003e\\1\u003c/code\u003e 表示引用第一个分组匹配到的内容,保证前后标签一致。\u003c/p\u003e\n\u003chr\u003e\n\u003ch1 id=\"9-最后速记清单\"\u003e9. 最后速记清单\u003c/h1\u003e\u003ch2 id=\"9-1-必背语法模板\"\u003e9.1 必背语法模板\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"%23%20%E7%B1%BB%0Aclass%20%E7%B1%BB%E5%90%8D(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20pass%0A%0A%23%20%E7%BB%A7%E6%89%BF%0Aclass%20%E5%AD%90%E7%B1%BB(%E7%88%B6%E7%B1%BB)%3A%0A%20%20%20%20pass%0A%0A%23%20%E8%B0%83%E7%88%B6%E7%B1%BB%0Asuper().%E6%96%B9%E6%B3%95%E5%90%8D()%0A%0A%23%20%E7%A7%81%E6%9C%89%E5%B1%9E%E6%80%A7%0Aself.__%E5%B1%9E%E6%80%A7%E5%90%8D%20%3D%20%E5%80%BC%0A%0A%23%20%E7%B1%BB%E6%96%B9%E6%B3%95%0A%40classmethod%0Adef%20%E6%96%B9%E6%B3%95%E5%90%8D(cls)%3A%0A%20%20%20%20pass%0A%0A%23%20%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95%0A%40staticmethod%0Adef%20%E6%96%B9%E6%B3%95%E5%90%8D()%3A%0A%20%20%20%20pass%0A%0A%23%20%E9%97%AD%E5%8C%85%0Adef%20outer()%3A%0A%20%20%20%20x%20%3D%201%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(x)%0A%20%20%20%20return%20inner%0A%0A%23%20%E9%80%9A%E7%94%A8%E8%A3%85%E9%A5%B0%E5%99%A8%0Adef%20decorator(fn)%3A%0A%20%20%20%20def%20inner(*args%2C%20**kwargs)%3A%0A%20%20%20%20%20%20%20%20return%20fn(*args%2C%20**kwargs)%0A%20%20%20%20return%20inner%0A%0A%23%20%E8%BF%9B%E7%A8%8B%0Amultiprocessing.Process(target%3D%E4%BB%BB%E5%8A%A1%E5%90%8D).start()%0A%0A%23%20%E7%BA%BF%E7%A8%8B%0Athreading.Thread(target%3D%E4%BB%BB%E5%8A%A1%E5%90%8D).start()%0A%0A%23%20socket%0Asocket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)%0A%0A%23%20%E6%AD%A3%E5%88%99%0Aresult%20%3D%20re.match(pattern%2C%20string)%0Aif%20result%3A%0A%20%20%20%20result.group()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003e类名\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 继承\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003e子类\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003e父类\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 调父类\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003esuper\u003c/span\u003e().方法名()\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 私有属性\u003c/span\u003e\n\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__属性名 = 值\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类方法\u003c/span\u003e\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@classmethod\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e方法名\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ecls\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 静态方法\u003c/span\u003e\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@staticmethod\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e方法名\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 闭包\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eouter\u003c/span\u003e():\n x = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(x)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 通用装饰器\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edecorator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e*args, **kwargs\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e fn(*args, **kwargs)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 进程\u003c/span\u003e\nmultiprocessing.Process(target=任务名).start()\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 线程\u003c/span\u003e\nthreading.Thread(target=任务名).start()\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# socket\u003c/span\u003e\nsocket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 正则\u003c/span\u003e\nresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(pattern, string)\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e result:\n result.group()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"9-2-高频易错点\"\u003e9.2 高频易错点\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e\u003ccode\u003eself\u003c/code\u003e 不是随便写的,它代表当前对象。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e__init__\u003c/code\u003e 创建对象时自动执行,不是手动调用的普通函数。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e__str__\u003c/code\u003e 必须 \u003ccode\u003ereturn\u003c/code\u003e 字符串,不能直接 \u003ccode\u003eprint\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e子类重写父类方法后,优先调用子类方法。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esuper().方法()\u003c/code\u003e 不写 \u003ccode\u003eself\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e私有属性 \u003ccode\u003e__xxx\u003c/code\u003e 类外不能直接访问,应写 \u003ccode\u003eget_xxx\u003c/code\u003e / \u003ccode\u003eset_xxx\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e装饰器如果原函数有返回值,内部函数也必须 \u003ccode\u003ereturn\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e多个装饰器:装饰时由内到外,执行时由外到内。\u003c/li\u003e\n\u003cli\u003e浅拷贝遇到嵌套可变对象,内层仍然共享。\u003c/li\u003e\n\u003cli\u003eTCP 客户端连接端口必须和服务端绑定端口一致。\u003c/li\u003e\n\u003cli\u003e进程不共享全局变量,线程共享全局变量。\u003c/li\u003e\n\u003cli\u003e线程共享数据要加锁,加锁后必须释放锁。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ere.match()\u003c/code\u003e 从开头匹配;想从中间找用 \u003ccode\u003ere.search()\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e正则里 \u003ccode\u003e.\u003c/code\u003e 想表示真正的小数点,要写 \u003ccode\u003e\\.\u003c/code\u003e 或使用原始字符串 \u003ccode\u003er\"\\.\"\u003c/code\u003e。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"9-3-用一句话串起来\"\u003e9.3 用一句话串起来\u003c/h2\u003e\u003cp\u003ePython 高级这一组课的主线是:先用\u003cstrong\u003e面向对象\u003c/strong\u003e把现实事物抽象成类和对象,再用\u003cstrong\u003e继承、封装、多态\u003c/strong\u003e提高代码复用和扩展性;遇到函数增强用\u003cstrong\u003e闭包和装饰器\u003c/strong\u003e,遇到对象复制要区分\u003cstrong\u003e浅拷贝和深拷贝\u003c/strong\u003e;做网络通信要掌握 \u003cstrong\u003eIP、端口、协议、socket、TCP\u003c/strong\u003e;做多任务要区分\u003cstrong\u003e进程和线程\u003c/strong\u003e;处理大数据遍历用\u003cstrong\u003e迭代器/生成器\u003c/strong\u003e;处理字符串规则匹配用\u003cstrong\u003e正则表达式\u003c/strong\u003e。\u003c/p\u003e\n","cover_image":"","category_id":83,"author_id":1,"status":"published","view_count":2,"is_pinned":0,"allow_comments":1,"published_at":"2026-05-05T09:10:42.639Z","created_at":"2026-05-05 08:47:58","updated_at":"2026-05-05 09:10:43","asset_dir":"Python-高级阶段快速复习","first_published_at":"2026-05-05T08:47:58.725Z","archived_at":null,"series_id":null,"series_order":0,"pinned_order":0,"category_name":"课程","category_slug":"课程","category_description":"课程相关","series_name":null,"series_slug":null,"series_description":null,"series_cover_image":null,"cover_image_sources":null,"category":{"id":83,"name":"课程","slug":"课程","description":"课程相关"},"series":null,"tags":[],"comment_count":0,"series_navigation":{"prev":null,"next":null}},"html":"\u003ch1 id=\"python-高级阶段快速复习\"\u003ePython 高级阶段快速复习\u003c/h1\u003e\u003cblockquote\u003e\n\u003cp\u003e用途:快速过一遍 PPT 核心内容。重点看:概念一句话、语法模板、易错点、典型代码。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"0-总复习路线\"\u003e0. 总复习路线\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e面向对象基础\u003c/strong\u003e:类、对象、self、属性、魔法方法。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e面向对象高级\u003c/strong\u003e:继承、重写、super、封装、多态、抽象类、类属性/类方法/静态方法。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOOP 综合案例\u003c/strong\u003e:学生管理系统,重点是“类怎么拆、数据怎么存、功能怎么循环”。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e闭包与装饰器\u003c/strong\u003e:闭包保存外层变量;装饰器在不改原函数的情况下增强功能。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e深浅拷贝\u003c/strong\u003e:浅拷贝只拷贝外层;深拷贝连嵌套对象也复制。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e网络编程\u003c/strong\u003e:IP、端口、协议;TCP;socket;服务端/客户端流程。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e进程与线程\u003c/strong\u003e:多任务、并发/并行、进程资源隔离、线程共享全局变量、互斥锁。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e迭代器、生成器、property、正则\u003c/strong\u003e:高级语法和字符串匹配。\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch1 id=\"1-面向对象基础\"\u003e1. 面向对象基础\u003c/h1\u003e\u003ch2 id=\"1-1-面向过程-vs-面向对象\"\u003e1.1 面向过程 vs 面向对象\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e思维\u003c/th\u003e\n\u003cth\u003e核心\u003c/th\u003e\n\u003cth\u003e例子\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e面向过程\u003c/td\u003e\n\u003ctd\u003e按步骤解决问题\u003c/td\u003e\n\u003ctd\u003e第一步开冰箱,第二步放大象,第三步关冰箱\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e面向对象\u003c/td\u003e\n\u003ctd\u003e找对象,让对象做事\u003c/td\u003e\n\u003ctd\u003e冰箱对象有“打开/关闭”方法,大象对象被放进去\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003e一句话:\u003c/strong\u003e 面向对象就是尽量用代码模拟现实世界,把“属性”和“行为”封装到对象中。\u003c/p\u003e\n\u003ch2 id=\"1-2-三大特性\"\u003e1.2 三大特性\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e特性\u003c/th\u003e\n\u003cth\u003e大白话\u003c/th\u003e\n\u003cth\u003e作用\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e封装\u003c/td\u003e\n\u003ctd\u003e把属性和方法放到类里,对外提供接口\u003c/td\u003e\n\u003ctd\u003e简化使用,提高安全性\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e继承\u003c/td\u003e\n\u003ctd\u003e子类复用父类的属性和方法\u003c/td\u003e\n\u003ctd\u003e减少重复代码\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e多态\u003c/td\u003e\n\u003ctd\u003e同一个方法/函数,传入不同对象表现不同\u003c/td\u003e\n\u003ctd\u003e解耦、扩展性强\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"1-3-类-对象-self\"\u003e1.3 类、对象、self\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20run(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E6%B1%BD%E8%BD%A6%E8%83%BD%E8%B7%91%22)%0A%0Acar%20%3D%20Car()%20%20%20%20%20%20%23%20%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%2F%E5%AE%9E%E4%BE%8B%E5%8C%96%0Acar.run()%20%20%20%20%20%20%20%20%23%20%E5%AF%B9%E8%B1%A1%E8%B0%83%E7%94%A8%E6%96%B9%E6%B3%95\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003erun\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"汽车能跑\"\u003c/span\u003e)\n\ncar = Car() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 创建对象/实例化\u003c/span\u003e\ncar.run() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 对象调用方法\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e类\u003c/strong\u003e:抽象模板,例如汽车图纸。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e对象\u003c/strong\u003e:具体实体,例如某一辆车。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eself\u003c/strong\u003e:指向当前调用方法的对象本身。谁调用方法,\u003ccode\u003eself\u003c/code\u003e 就是谁。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20run(self)%3A%0A%20%20%20%20%20%20%20%20print(self)%20%20%20%23%20%E5%BD%93%E5%89%8D%E5%AF%B9%E8%B1%A1%0A%0Acar1%20%3D%20Car()%0Acar2%20%3D%20Car()%0Acar1.run()%0Acar2.run()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003erun\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 当前对象\u003c/span\u003e\n\ncar1 = Car()\ncar2 = Car()\ncar1.run()\ncar2.run()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e类内部调用自己的属性:\u003ccode\u003eself.属性名\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e类内部调用自己的方法:\u003ccode\u003eself.方法名()\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e类外部调用:\u003ccode\u003e对象名.属性名\u003c/code\u003e、\u003ccode\u003e对象名.方法名()\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"1-4-对象属性\"\u003e1.4 对象属性\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20show(self)%3A%0A%20%20%20%20%20%20%20%20print(self.color)%0A%20%20%20%20%20%20%20%20print(self.number)%0A%0Acar%20%3D%20Car()%0Acar.color%20%3D%20%22%E7%BA%A2%E8%89%B2%22%20%20%20%20%20%20%23%20%E7%B1%BB%E5%A4%96%E9%83%A8%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%0Acar.number%20%3D%204%0Acar.show()%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E7%B1%BB%E5%86%85%E9%83%A8%E9%80%9A%E8%BF%87%20self%20%E8%AE%BF%E9%97%AE\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eshow\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.color)\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.number)\n\ncar = Car()\ncar.color = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"红色\"\u003c/span\u003e \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类外部添加属性\u003c/span\u003e\ncar.number = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e\ncar.show() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类内部通过 self 访问\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e一般更推荐在 \u003ccode\u003e__init__\u003c/code\u003e 中统一初始化属性,而不是随用随加。\u003c/p\u003e\n\u003ch2 id=\"1-5-魔法方法\"\u003e1.5 魔法方法\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e方法\u003c/th\u003e\n\u003cth\u003e什么时候自动调用\u003c/th\u003e\n\u003cth\u003e作用\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e__init__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e创建对象时\u003c/td\u003e\n\u003ctd\u003e初始化属性\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e__str__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eprint(对象)\u003c/code\u003e 时\u003c/td\u003e\n\u003ctd\u003e返回对象的字符串描述\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e__del__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e对象被删除/程序结束时\u003c/td\u003e\n\u003ctd\u003e释放资源或观察对象销毁\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Car(object)%3A%0A%20%20%20%20def%20__init__(self%2C%20color%2C%20number)%3A%0A%20%20%20%20%20%20%20%20self.color%20%3D%20color%0A%20%20%20%20%20%20%20%20self.number%20%3D%20number%0A%0A%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20return%20f%22%E9%A2%9C%E8%89%B2%EF%BC%9A%7Bself.color%7D%EF%BC%8C%E8%BD%AE%E8%83%8E%E6%95%B0%EF%BC%9A%7Bself.number%7D%22%0A%0A%20%20%20%20def%20__del__(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AF%B9%E8%B1%A1%E8%A2%AB%E5%88%A0%E9%99%A4%22)%0A%0Acar%20%3D%20Car(%22Red%22%2C%204)%0Aprint(car)%0Adel%20car\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eCar\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, color, number\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.color = color\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.number = number\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__str__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"颜色:\u003cspan class=\"hljs-subst\"\u003e{self.color}\u003c/span\u003e,轮胎数:\u003cspan class=\"hljs-subst\"\u003e{self.number}\u003c/span\u003e\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__del__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"对象被删除\"\u003c/span\u003e)\n\ncar = Car(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"Red\"\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(car)\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edel\u003c/span\u003e car\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e记忆:\u003c/strong\u003e \u003ccode\u003e__init__\u003c/code\u003e 管出生,\u003ccode\u003e__str__\u003c/code\u003e 管打印,\u003ccode\u003e__del__\u003c/code\u003e 管销毁。\u003c/p\u003e\n\u003ch2 id=\"1-6-综合小案例思路-烤地瓜\"\u003e1.6 综合小案例思路:烤地瓜\u003c/h2\u003e\u003cp\u003e对象:地瓜。\u003c/p\u003e\n\u003cp\u003e属性:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ecook_time\u003c/code\u003e:总共烤了多久\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecook_state\u003c/code\u003e:当前状态\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003econdiments\u003c/code\u003e:调料列表\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e方法:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ecook(time)\u003c/code\u003e:累计时间,并根据总时间更新状态\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eadd_condiments(condiment)\u003c/code\u003e:添加调料\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e__str__()\u003c/code\u003e:输出地瓜状态\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e核心代码:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20SweetPotato(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.cook_time%20%3D%200%0A%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%94%9F%E7%9A%84%22%0A%20%20%20%20%20%20%20%20self.condiments%20%3D%20%5B%5D%0A%0A%20%20%20%20def%20cook(self%2C%20time)%3A%0A%20%20%20%20%20%20%20%20self.cook_time%20%2B%3D%20time%0A%20%20%20%20%20%20%20%20if%20self.cook_time%20%3C%203%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%94%9F%E7%9A%84%22%0A%20%20%20%20%20%20%20%20elif%20self.cook_time%20%3C%205%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E5%8D%8A%E7%94%9F%E4%B8%8D%E7%86%9F%22%0A%20%20%20%20%20%20%20%20elif%20self.cook_time%20%3C%208%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%86%9F%E4%BA%86%22%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.cook_state%20%3D%20%22%E7%83%A4%E7%B3%8A%E4%BA%86%22%0A%0A%20%20%20%20def%20add_condiments(self%2C%20condiment)%3A%0A%20%20%20%20%20%20%20%20self.condiments.append(condiment)%0A%0A%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20return%20f%22%E6%97%B6%E9%97%B4%EF%BC%9A%7Bself.cook_time%7D%EF%BC%8C%E7%8A%B6%E6%80%81%EF%BC%9A%7Bself.cook_state%7D%EF%BC%8C%E8%B0%83%E6%96%99%EF%BC%9A%7Bself.condiments%7D%22\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSweetPotato\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"生的\"\u003c/span\u003e\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.condiments = []\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecook\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, time\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time += time\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time \u0026lt; \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"生的\"\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time \u0026lt; \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"半生不熟\"\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_time \u0026lt; \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e8\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"熟了\"\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.cook_state = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"烤糊了\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_condiments\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, condiment\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.condiments.append(condiment)\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__str__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"时间:\u003cspan class=\"hljs-subst\"\u003e{self.cook_time}\u003c/span\u003e,状态:\u003cspan class=\"hljs-subst\"\u003e{self.cook_state}\u003c/span\u003e,调料:\u003cspan class=\"hljs-subst\"\u003e{self.condiments}\u003c/span\u003e\"\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"2-面向对象高级\"\u003e2. 面向对象高级\u003c/h1\u003e\u003ch2 id=\"2-1-类的三种写法\"\u003e2.1 类的三种写法\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Teacher%3A%0A%20%20%20%20pass%0A%0Aclass%20Teacher()%3A%0A%20%20%20%20pass%0A%0Aclass%20Teacher(object)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eTeacher\u003c/span\u003e:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eTeacher\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eTeacher\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e课件建议重点使用:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20%E7%B1%BB%E5%90%8D(object)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003e类名\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e补充理解:Python 3 中默认继承 \u003ccode\u003eobject\u003c/code\u003e,所以 \u003ccode\u003eclass A:\u003c/code\u003e 和 \u003ccode\u003eclass A(object):\u003c/code\u003e 基本等价,但写 \u003ccode\u003eobject\u003c/code\u003e 更利于初学时理解“所有类最终继承 object”。\u003c/p\u003e\n\u003ch2 id=\"2-2-继承\"\u003e2.2 继承\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Father(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.sex%20%3D%20%22%E7%94%B7%22%0A%0A%20%20%20%20def%20walk(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E6%95%A3%E6%AD%A5%22)%0A%0Aclass%20Son(Father)%3A%0A%20%20%20%20pass%0A%0Ason%20%3D%20Son()%0Aprint(son.sex)%0Ason.walk()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.sex = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"男\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ewalk\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"散步\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\nson = Son()\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(son.sex)\nson.walk()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e父类/基类\u003c/strong\u003e:被继承的类。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e子类/派生类\u003c/strong\u003e:继承别人的类。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e作用\u003c/strong\u003e:复用代码,减少重复。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e本质\u003c/strong\u003e:子类对象可以使用父类的属性和方法。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-3-单继承与多继承\"\u003e2.3 单继承与多继承\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Son(Father)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Son(Father%2C%20Mother)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(Father, Mother):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e多继承时,如果多个父类有同名属性或方法,默认按继承顺序查找,先找第一个父类。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"print(Son.__mro__)%0Aprint(Son.mro())\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(Son.__mro__)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(Son.mro())\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003eMRO\u003c/code\u003e:Method Resolution Order,方法解析顺序。\u003c/p\u003e\n\u003ch2 id=\"2-4-重写与调用父类方法\"\u003e2.4 重写与调用父类方法\u003c/h2\u003e\u003cp\u003e子类定义了和父类同名的方法或属性,就会优先使用子类自己的。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Father(object)%3A%0A%20%20%20%20def%20make_cake(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%88%B6%E7%B1%BB%E9%85%8D%E6%96%B9%22)%0A%0Aclass%20Son(Father)%3A%0A%20%20%20%20def%20make_cake(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%90%E7%B1%BB%E6%96%B0%E9%85%8D%E6%96%B9%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emake_cake\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"父类配方\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emake_cake\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"子类新配方\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e子类想调用父类方法:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Son(Father)%3A%0A%20%20%20%20def%20make_old_cake(self)%3A%0A%20%20%20%20%20%20%20%20super().make_cake()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eSon\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eFather\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emake_old_cake\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003esuper\u003c/span\u003e().make_cake()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e也可以写:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"Father.make_cake(self)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eFather.make_cake(\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e但更推荐 \u003ccode\u003esuper()\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003esuper().方法名()\u003c/code\u003e 不需要手动传 \u003ccode\u003eself\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e父类名.方法名(self)\u003c/code\u003e 需要手动传 \u003ccode\u003eself\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e多继承时 \u003ccode\u003esuper()\u003c/code\u003e 会按 MRO 走,复杂多继承要谨慎。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-5-多层继承\"\u003e2.5 多层继承\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20A(object)%3A%0A%20%20%20%20pass%0A%0Aclass%20B(A)%3A%0A%20%20%20%20pass%0A%0Aclass%20C(B)%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eA\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eB\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eA\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eC\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eB\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003eC\u003c/code\u003e 可以继承 \u003ccode\u003eB\u003c/code\u003e 的内容,也能间接继承 \u003ccode\u003eA\u003c/code\u003e 的内容。\u003c/p\u003e\n\u003ch2 id=\"2-6-封装与私有属性\"\u003e2.6 封装与私有属性\u003c/h2\u003e\u003cp\u003e私有属性/方法:在名字前加两个下划线 \u003ccode\u003e__\u003c/code\u003e。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.__money%20%3D%201000%0A%0A%20%20%20%20def%20get_money(self)%3A%0A%20%20%20%20%20%20%20%20return%20self.__money%0A%0A%20%20%20%20def%20set_money(self%2C%20money)%3A%0A%20%20%20%20%20%20%20%20self.__money%20%3D%20money\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__money = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1000\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eget_money\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__money\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eset_money\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, money\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__money = money\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e私有方法:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__secret(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%A7%81%E6%9C%89%E6%96%B9%E6%B3%95%22)%0A%0A%20%20%20%20def%20call_secret(self)%3A%0A%20%20%20%20%20%20%20%20self.__secret()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__secret\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"私有方法\"\u003c/span\u003e)\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecall_secret\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__secret()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e记忆:\u003c/strong\u003e 私有成员不能在类外直接访问,一般通过公有方法间接访问。\u003c/p\u003e\n\u003ch2 id=\"2-7-多态\"\u003e2.7 多态\u003c/h2\u003e\u003cp\u003e多态:同一个调用方式,传入不同子类对象,产生不同效果。\u003c/p\u003e\n\u003cp\u003e成立条件按课件记:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e有继承。\u003c/li\u003e\n\u003cli\u003e子类重写父类方法。\u003c/li\u003e\n\u003cli\u003e父类引用指向子类对象,也就是框架函数接收父类类型,实际传入子类对象。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20HeroFighter(object)%3A%0A%20%20%20%20def%20power(self)%3A%0A%20%20%20%20%20%20%20%20return%2060%0A%0Aclass%20AdvHeroFighter(HeroFighter)%3A%0A%20%20%20%20def%20power(self)%3A%0A%20%20%20%20%20%20%20%20return%2080%0A%0Aclass%20EnemyFighter(object)%3A%0A%20%20%20%20def%20attack(self)%3A%0A%20%20%20%20%20%20%20%20return%2070%0A%0Adef%20object_play(hero%3A%20HeroFighter%2C%20enemy%3A%20EnemyFighter)%3A%0A%20%20%20%20if%20hero.power()%20%3E%20enemy.attack()%3A%0A%20%20%20%20%20%20%20%20print(%22%E8%8B%B1%E9%9B%84%E8%83%9C%E5%88%A9%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E8%8B%B1%E9%9B%84%E5%A4%B1%E8%B4%A5%22)%0A%0Aobject_play(HeroFighter()%2C%20EnemyFighter())%0Aobject_play(AdvHeroFighter()%2C%20EnemyFighter())\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eHeroFighter\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003epower\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e60\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eAdvHeroFighter\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eHeroFighter\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003epower\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e80\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eEnemyFighter\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eattack\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e70\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eobject_play\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ehero: HeroFighter, enemy: EnemyFighter\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e hero.power() \u0026gt; enemy.attack():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"英雄胜利\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"英雄失败\"\u003c/span\u003e)\n\nobject_play(HeroFighter(), EnemyFighter())\nobject_play(AdvHeroFighter(), EnemyFighter())\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e好处:\u003c/strong\u003e 平台函数 \u003ccode\u003eobject_play\u003c/code\u003e 不需要改,后来新增更强的战机类也能接入,这就是解耦和扩展。\u003c/p\u003e\n\u003ch2 id=\"2-8-抽象类-接口思想\"\u003e2.8 抽象类/接口思想\u003c/h2\u003e\u003cp\u003e抽象类:父类只规定“必须有什么方法”,具体怎么做交给子类。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Animal(object)%3A%0A%20%20%20%20def%20speak(self)%3A%0A%20%20%20%20%20%20%20%20pass%0A%0Aclass%20Dog(Animal)%3A%0A%20%20%20%20def%20speak(self)%3A%0A%20%20%20%20%20%20%20%20print(%22%E6%B1%AA%E6%B1%AA%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eAnimal\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003espeak\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eDog\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eAnimal\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003espeak\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"汪汪\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e一句话:\u003c/strong\u003e 抽象类像行业标准,子类像不同厂家,各自实现标准。\u003c/p\u003e\n\u003ch2 id=\"2-9-类属性-类方法-静态方法\"\u003e2.9 类属性、类方法、静态方法\u003c/h2\u003e\u003ch3 id=\"对象属性\"\u003e对象属性\u003c/h3\u003e\u003cp\u003e每个对象自己一份。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Phone(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.brand%20%3D%20%22%E5%8D%8E%E4%B8%BA%22\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePhone\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.brand = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"华为\"\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"类属性\"\u003e类属性\u003c/h3\u003e\u003cp\u003e属于类,被所有对象共享。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20count%20%3D%200%0A%0Aprint(Person.count)%20%20%20%23%20%E6%8E%A8%E8%8D%90\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n count = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(Person.count) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 推荐\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"类方法\"\u003e类方法\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Dog(object)%3A%0A%20%20%20%20%40classmethod%0A%20%20%20%20def%20eat(cls)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%B0%8F%E7%8B%97%E9%83%BD%E5%96%9C%E6%AC%A2%E9%AA%A8%E5%A4%B4%22)%0A%0ADog.eat()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eDog\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @classmethod\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eeat\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ecls\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小狗都喜欢骨头\"\u003c/span\u003e)\n\nDog.eat()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e第一个参数是 \u003ccode\u003ecls\u003c/code\u003e,代表类本身。\u003c/li\u003e\n\u003cli\u003e常用于访问/修改类属性。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"静态方法\"\u003e静态方法\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Game(object)%3A%0A%20%20%20%20%40staticmethod%0A%20%20%20%20def%20show_menu()%3A%0A%20%20%20%20%20%20%20%20print(%221.%E5%BC%80%E5%A7%8B%202.%E6%9A%82%E5%81%9C%200.%E9%80%80%E5%87%BA%22)%0A%0AGame.show_menu()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eGame\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @staticmethod\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eshow_menu\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"1.开始 2.暂停 0.退出\"\u003c/span\u003e)\n\nGame.show_menu()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e不需要 \u003ccode\u003eself\u003c/code\u003e,也不需要 \u003ccode\u003ecls\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e只是放在类里的普通工具函数。\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch1 id=\"3-学生管理系统综合案例\"\u003e3. 学生管理系统综合案例\u003c/h1\u003e\u003ch2 id=\"3-1-项目拆分\"\u003e3.1 项目拆分\u003c/h2\u003e\u003cp\u003e推荐文件结构:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"StudentManagerSystem%2F%0A%E2%94%9C%E2%94%80%E2%94%80%20main.py%20%20%20%20%20%20%20%20%20%20%23%20%E7%A8%8B%E5%BA%8F%E5%85%A5%E5%8F%A3%0A%E2%94%9C%E2%94%80%E2%94%80%20student.py%20%20%20%20%20%20%20%23%20%E5%AD%A6%E7%94%9F%E7%B1%BB%0A%E2%94%94%E2%94%80%E2%94%80%20studentcms.py%20%20%20%20%23%20%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%E7%B1%BB\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eStudentManagerSystem/\n├── main.py \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 程序入口\u003c/span\u003e\n├── student.py \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 学生类\u003c/span\u003e\n└── studentcms.py \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 管理系统类\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e角色:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003eStudent\u003c/code\u003e:表示一个学生。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eStudentCms\u003c/code\u003e:管理学生信息。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"3-2-student-类\"\u003e3.2 Student 类\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Student(object)%3A%0A%20%20%20%20def%20__init__(self%2C%20name%2C%20age%2C%20gender%2C%20mobile%2C%20description)%3A%0A%20%20%20%20%20%20%20%20self.name%20%3D%20name%0A%20%20%20%20%20%20%20%20self.age%20%3D%20age%0A%20%20%20%20%20%20%20%20self.gender%20%3D%20gender%0A%20%20%20%20%20%20%20%20self.mobile%20%3D%20mobile%0A%20%20%20%20%20%20%20%20self.description%20%3D%20description%0A%0A%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20return%20f%22%7Bself.name%7D%2C%20%7Bself.age%7D%2C%20%7Bself.gender%7D%2C%20%7Bself.mobile%7D%2C%20%7Bself.description%7D%22\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eStudent\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, name, age, gender, mobile, description\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.name = name\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.age = age\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.gender = gender\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.mobile = mobile\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.description = description\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__str__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"\u003cspan class=\"hljs-subst\"\u003e{self.name}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.age}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.gender}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.mobile}\u003c/span\u003e, \u003cspan class=\"hljs-subst\"\u003e{self.description}\u003c/span\u003e\"\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-3-管理系统核心属性\"\u003e3.3 管理系统核心属性\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20StudentCms(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.student_list%20%3D%20%5B%5D%20%20%20%23%20%E5%88%97%E8%A1%A8%E4%B8%AD%E5%AD%98%E5%AD%A6%E7%94%9F%E5%AF%B9%E8%B1%A1\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eStudentCms\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list = [] \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 列表中存学生对象\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-4-主循环框架\"\u003e3.4 主循环框架\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20start(self)%3A%0A%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20self.show_operate_view()%0A%20%20%20%20%20%20%20%20number%20%3D%20int(input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E6%93%8D%E4%BD%9C%E5%BA%8F%E5%8F%B7%EF%BC%9A%22))%0A%0A%20%20%20%20%20%20%20%20if%20number%20%3D%3D%201%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.add_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%202%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.update_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%203%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.delete_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%204%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.query_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%205%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.show_all_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%206%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.save_student()%0A%20%20%20%20%20%20%20%20elif%20number%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E5%BA%8F%E5%8F%B7%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003estart\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewhile\u003c/span\u003e \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.show_operate_view()\n number = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eint\u003c/span\u003e(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入操作序号:\"\u003c/span\u003e))\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.add_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.update_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.delete_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.query_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.show_all_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e6\u003c/span\u003e:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.save_student()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e number == \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"序号不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-5-增删改查思路\"\u003e3.5 增删改查思路\u003c/h2\u003e\u003ch3 id=\"添加\"\u003e添加\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20add_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20age%20%3D%20int(input(%22%E5%B9%B4%E9%BE%84%EF%BC%9A%22))%0A%20%20%20%20gender%20%3D%20input(%22%E6%80%A7%E5%88%AB%EF%BC%9A%22)%0A%20%20%20%20mobile%20%3D%20input(%22%E8%81%94%E7%B3%BB%E6%96%B9%E5%BC%8F%EF%BC%9A%22)%0A%20%20%20%20description%20%3D%20input(%22%E7%AE%80%E4%BB%8B%EF%BC%9A%22)%0A%0A%20%20%20%20student%20%3D%20Student(name%2C%20age%2C%20gender%2C%20mobile%2C%20description)%0A%20%20%20%20self.student_list.append(student)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"姓名:\"\u003c/span\u003e)\n age = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eint\u003c/span\u003e(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"年龄:\"\u003c/span\u003e))\n gender = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"性别:\"\u003c/span\u003e)\n mobile = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"联系方式:\"\u003c/span\u003e)\n description = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"简介:\"\u003c/span\u003e)\n\n student = Student(name, age, gender, mobile, description)\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list.append(student)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"删除\"\u003e删除\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20delete_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E8%A6%81%E5%88%A0%E9%99%A4%E7%9A%84%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20if%20student.name%20%3D%3D%20name%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.student_list.remove(student)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E5%88%A0%E9%99%A4%E6%88%90%E5%8A%9F%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%A6%E7%94%9F%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edelete_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入要删除的姓名:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e student.name == name:\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list.remove(student)\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"删除成功\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"学生不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"修改\"\u003e修改\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20update_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E8%A6%81%E4%BF%AE%E6%94%B9%E7%9A%84%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20if%20student.name%20%3D%3D%20name%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20student.age%20%3D%20int(input(%22%E6%96%B0%E5%B9%B4%E9%BE%84%EF%BC%9A%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20student.gender%20%3D%20input(%22%E6%96%B0%E6%80%A7%E5%88%AB%EF%BC%9A%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20student.mobile%20%3D%20input(%22%E6%96%B0%E8%81%94%E7%B3%BB%E6%96%B9%E5%BC%8F%EF%BC%9A%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20student.description%20%3D%20input(%22%E6%96%B0%E7%AE%80%E4%BB%8B%EF%BC%9A%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%A6%E7%94%9F%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eupdate_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入要修改的姓名:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e student.name == name:\n student.age = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eint\u003c/span\u003e(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新年龄:\"\u003c/span\u003e))\n student.gender = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新性别:\"\u003c/span\u003e)\n student.mobile = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新联系方式:\"\u003c/span\u003e)\n student.description = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"新简介:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"学生不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"查询\"\u003e查询\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20query_student(self)%3A%0A%20%20%20%20name%20%3D%20input(%22%E8%AF%B7%E8%BE%93%E5%85%A5%E8%A6%81%E6%9F%A5%E8%AF%A2%E7%9A%84%E5%A7%93%E5%90%8D%EF%BC%9A%22)%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20if%20name%20in%20student.name%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(student)%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%AD%A6%E7%94%9F%E4%B8%8D%E5%AD%98%E5%9C%A8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003equery_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n name = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003einput\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"请输入要查询的姓名:\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e name \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e student.name:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(student)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ebreak\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelse\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"学生不存在\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"显示全部\"\u003e显示全部\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20show_all_student(self)%3A%0A%20%20%20%20for%20student%20in%20self.student_list%3A%0A%20%20%20%20%20%20%20%20print(student)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eshow_all_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(student)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"3-6-保存与加载\"\u003e3.6 保存与加载\u003c/h2\u003e\u003cp\u003e保存对象时不能直接保存对象内存地址,要转成字典。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20save_student(self)%3A%0A%20%20%20%20with%20open(%22student.data%22%2C%20%22w%22%2C%20encoding%3D%22utf-8%22)%20as%20f%3A%0A%20%20%20%20%20%20%20%20data%20%3D%20%5Bstudent.__dict__%20for%20student%20in%20self.student_list%5D%0A%20%20%20%20%20%20%20%20f.write(str(data))\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003esave_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewith\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eopen\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"student.data\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"w\"\u003c/span\u003e, encoding=\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e) \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eas\u003c/span\u003e f:\n data = [student.__dict__ \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e student \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list]\n f.write(\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003estr\u003c/span\u003e(data))\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e加载:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20load_student(self)%3A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20with%20open(%22student.data%22%2C%20%22r%22%2C%20encoding%3D%22utf-8%22)%20as%20f%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20content%20%3D%20f.read()%0A%20%20%20%20except%20FileNotFoundError%3A%0A%20%20%20%20%20%20%20%20content%20%3D%20%22%5B%5D%22%0A%0A%20%20%20%20if%20not%20content%3A%0A%20%20%20%20%20%20%20%20content%20%3D%20%22%5B%5D%22%0A%0A%20%20%20%20data_list%20%3D%20eval(content)%0A%20%20%20%20self.student_list%20%3D%20%5B%0A%20%20%20%20%20%20%20%20Student(d%5B%22name%22%5D%2C%20d%5B%22age%22%5D%2C%20d%5B%22gender%22%5D%2C%20d%5B%22mobile%22%5D%2C%20d%5B%22description%22%5D)%0A%20%20%20%20%20%20%20%20for%20d%20in%20data_list%0A%20%20%20%20%5D\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eload_student\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003etry\u003c/span\u003e:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewith\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eopen\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"student.data\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"r\"\u003c/span\u003e, encoding=\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e) \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eas\u003c/span\u003e f:\n content = f.read()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eexcept\u003c/span\u003e FileNotFoundError:\n content = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"[]\"\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003enot\u003c/span\u003e content:\n content = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"[]\"\u003c/span\u003e\n\n data_list = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eeval\u003c/span\u003e(content)\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.student_list = [\n Student(d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"name\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"age\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"gender\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"mobile\"\u003c/span\u003e], d[\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"description\"\u003c/span\u003e])\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e d \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e data_list\n ]\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课件中有的地方用了 \u003ccode\u003estudent_datas\u003c/code\u003e,有的地方用了 \u003ccode\u003estudent_list\u003c/code\u003e,实际写代码时必须统一变量名。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eeval()\u003c/code\u003e 学习案例可以用,真实开发更推荐 \u003ccode\u003ejson\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003efor ... else\u003c/code\u003e:循环没有被 \u003ccode\u003ebreak\u003c/code\u003e 打断,才执行 \u003ccode\u003eelse\u003c/code\u003e。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-7-main-py\"\u003e3.7 main.py\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"from%20studentcms%20import%20StudentCms%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20cms%20%3D%20StudentCms()%0A%20%20%20%20cms.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efrom\u003c/span\u003e studentcms \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e StudentCms\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e __name__ == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"__main__\"\u003c/span\u003e:\n cms = StudentCms()\n cms.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"4-闭包-装饰器-深浅拷贝\"\u003e4. 闭包、装饰器、深浅拷贝\u003c/h1\u003e\u003ch2 id=\"4-1-闭包\"\u003e4.1 闭包\u003c/h2\u003e\u003cp\u003e闭包作用:保存外部函数中的变量,让它在外部函数执行完后仍然能被内部函数使用。\u003c/p\u003e\n\u003cp\u003e闭包三条件:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e有函数嵌套。\u003c/li\u003e\n\u003cli\u003e内部函数使用外部函数变量。\u003c/li\u003e\n\u003cli\u003e外部函数返回内部函数。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20func_out(num1)%3A%0A%20%20%20%20def%20func_inner(num2)%3A%0A%20%20%20%20%20%20%20%20print(num1%20%2B%20num2)%0A%20%20%20%20return%20func_inner%0A%0Af%20%3D%20func_out(10)%0Af(1)%20%20%20%23%2011\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_out\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003enum1\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_inner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003enum2\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(num1 + num2)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e func_inner\n\nf = func_out(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e10\u003c/span\u003e)\nf(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 11\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"4-2-nonlocal\"\u003e4.2 nonlocal\u003c/h2\u003e\u003cp\u003e内部函数要修改外部函数变量时,用 \u003ccode\u003enonlocal\u003c/code\u003e。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20func_out()%3A%0A%20%20%20%20a%20%3D%20100%0A%0A%20%20%20%20def%20func_inner()%3A%0A%20%20%20%20%20%20%20%20nonlocal%20a%0A%20%20%20%20%20%20%20%20a%20%2B%3D%201%0A%20%20%20%20%20%20%20%20print(a)%0A%0A%20%20%20%20return%20func_inner\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_out\u003c/span\u003e():\n a = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e100\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003efunc_inner\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003enonlocal\u003c/span\u003e a\n a += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(a)\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e func_inner\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eglobal\u003c/code\u003e:声明全局变量。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enonlocal\u003c/code\u003e:声明外层函数的局部变量。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"4-3-装饰器\"\u003e4.3 装饰器\u003c/h2\u003e\u003cp\u003e装饰器作用:\u003cstrong\u003e不修改原函数代码的前提下,给原函数增加额外功能。\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e装饰器本质:闭包函数。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20check(fn)%3A%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%99%BB%E5%BD%95%E9%AA%8C%E8%AF%81%22)%0A%20%20%20%20%20%20%20%20fn()%0A%20%20%20%20return%20inner%0A%0A%40check%0Adef%20comment()%3A%0A%20%20%20%20print(%22%E5%8F%91%E8%A1%A8%E8%AF%84%E8%AE%BA%22)%0A%0Acomment()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003echeck\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"登录验证\"\u003c/span\u003e)\n fn()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecomment\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"发表评论\"\u003c/span\u003e)\n\ncomment()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e解释器遇到:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"%40check%0Adef%20comment()%3A%0A%20%20%20%20pass\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecomment\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e等价于:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"comment%20%3D%20check(comment)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ecomment = check(comment)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"4-4-通用装饰器模板\"\u003e4.4 通用装饰器模板\u003c/h2\u003e\u003cp\u003e原函数有参数、有返回值时,内部函数也要接收参数并返回结果。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20decorator(fn)%3A%0A%20%20%20%20def%20inner(*args%2C%20**kwargs)%3A%0A%20%20%20%20%20%20%20%20print(%22%E9%A2%9D%E5%A4%96%E5%8A%9F%E8%83%BD%22)%0A%20%20%20%20%20%20%20%20return%20fn(*args%2C%20**kwargs)%0A%20%20%20%20return%20inner\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edecorator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e*args, **kwargs\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"额外功能\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e fn(*args, **kwargs)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e一句话:\u003c/strong\u003e 原函数有没有参数、有没有返回值,装饰器内部函数就要对应处理。\u003c/p\u003e\n\u003ch2 id=\"4-5-多个装饰器\"\u003e4.5 多个装饰器\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20check_user(fn)%3A%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(%22%E7%94%A8%E6%88%B7%E5%90%8D%E5%AF%86%E7%A0%81%E9%AA%8C%E8%AF%81%22)%0A%20%20%20%20%20%20%20%20fn()%0A%20%20%20%20return%20inner%0A%0Adef%20check_code(fn)%3A%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(%22%E9%AA%8C%E8%AF%81%E7%A0%81%E9%AA%8C%E8%AF%81%22)%0A%20%20%20%20%20%20%20%20fn()%0A%20%20%20%20return%20inner%0A%0A%40check_user%0A%40check_code%0Adef%20comment()%3A%0A%20%20%20%20print(%22%E5%8F%91%E8%A1%A8%E8%AF%84%E8%AE%BA%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003echeck_user\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"用户名密码验证\"\u003c/span\u003e)\n fn()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003echeck_code\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"验证码验证\"\u003c/span\u003e)\n fn()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check_user\u003c/span\u003e\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@check_code\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecomment\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"发表评论\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e装饰过程:离函数最近的先装饰,由内到外。\u003c/p\u003e\n\u003cp\u003e等价于:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"comment%20%3D%20check_user(check_code(comment))\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ecomment = check_user(check_code(comment))\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e调用执行时:外层先执行。\u003c/p\u003e\n\u003ch2 id=\"4-6-带参数的装饰器\"\u003e4.6 带参数的装饰器\u003c/h2\u003e\u003cp\u003e带参数装饰器 = 外面再包一层函数,用来接收装饰器参数。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20logging(flag)%3A%0A%20%20%20%20def%20decorator(fn)%3A%0A%20%20%20%20%20%20%20%20def%20inner(a%2C%20b)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20flag%20%3D%3D%20%22%2B%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E6%AD%A3%E5%9C%A8%E5%8A%A0%E6%B3%95%E8%AE%A1%E7%AE%97%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20elif%20flag%20%3D%3D%20%22-%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22%E6%AD%A3%E5%9C%A8%E5%87%8F%E6%B3%95%E8%AE%A1%E7%AE%97%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20fn(a%2C%20b)%0A%20%20%20%20%20%20%20%20return%20inner%0A%20%20%20%20return%20decorator%0A%0A%40logging(%22%2B%22)%0Adef%20add(a%2C%20b)%3A%0A%20%20%20%20return%20a%20%2B%20b%0A%0A%40logging(%22-%22)%0Adef%20sub(a%2C%20b)%3A%0A%20%20%20%20return%20a%20-%20b\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003elogging\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eflag\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edecorator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ea, b\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e flag == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"+\"\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"正在加法计算\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eelif\u003c/span\u003e flag == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"-\"\u003c/span\u003e:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"正在减法计算\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e fn(a, b)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e decorator\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@logging(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"+\"\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ea, b\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e a + b\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@logging(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"-\"\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003esub\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ea, b\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e a - b\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e记忆结构:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20%E5%A4%96%E5%B1%82%E5%87%BD%E6%95%B0(%E8%A3%85%E9%A5%B0%E5%99%A8%E5%8F%82%E6%95%B0)%3A%0A%20%20%20%20def%20%E8%A3%85%E9%A5%B0%E5%99%A8(%E5%8E%9F%E5%87%BD%E6%95%B0)%3A%0A%20%20%20%20%20%20%20%20def%20%E5%86%85%E5%B1%82%E5%87%BD%E6%95%B0(*args%2C%20**kwargs)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%E5%8E%9F%E5%87%BD%E6%95%B0(*args%2C%20**kwargs)%0A%20%20%20%20%20%20%20%20return%20%E5%86%85%E5%B1%82%E5%87%BD%E6%95%B0%0A%20%20%20%20return%20%E8%A3%85%E9%A5%B0%E5%99%A8\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e外层函数\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e装饰器参数\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e装饰器\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e原函数\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e内层函数\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e*args, **kwargs\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e 原函数(*args, **kwargs)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e 内层函数\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e 装饰器\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"4-7-浅拷贝与深拷贝\"\u003e4.7 浅拷贝与深拷贝\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20copy%0A%0Ab%20%3D%20copy.copy(a)%20%20%20%20%20%20%20%23%20%E6%B5%85%E6%8B%B7%E8%B4%9D%0Ac%20%3D%20copy.deepcopy(a)%20%20%20%23%20%E6%B7%B1%E6%8B%B7%E8%B4%9D\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e copy\n\nb = copy.copy(a) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 浅拷贝\u003c/span\u003e\nc = copy.deepcopy(a) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 深拷贝\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e类型\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003cth\u003e嵌套对象是否独立\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e赋值\u003c/td\u003e\n\u003ctd\u003e多个变量指向同一个对象\u003c/td\u003e\n\u003ctd\u003e不独立\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e浅拷贝\u003c/td\u003e\n\u003ctd\u003e只复制最外层对象\u003c/td\u003e\n\u003ctd\u003e内层嵌套对象仍共享\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e深拷贝\u003c/td\u003e\n\u003ctd\u003e递归复制所有层级\u003c/td\u003e\n\u003ctd\u003e基本独立\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e例子:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20copy%0A%0Aa%20%3D%20%5B1%2C%202%2C%20%5B3%2C%204%5D%5D%0Ab%20%3D%20copy.copy(a)%0Ac%20%3D%20copy.deepcopy(a)%0A%0Aa%5B2%5D.append(5)%0Aprint(b)%20%20%23%20%5B1%2C%202%2C%20%5B3%2C%204%2C%205%5D%5D%EF%BC%8C%E5%8F%97%E5%BD%B1%E5%93%8D%0Aprint(c)%20%20%23%20%5B1%2C%202%2C%20%5B3%2C%204%5D%5D%EF%BC%8C%E4%B8%8D%E5%8F%97%E5%BD%B1%E5%93%8D\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e copy\n\na = [\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e, [\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e4\u003c/span\u003e]]\nb = copy.copy(a)\nc = copy.deepcopy(a)\n\na[\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e].append(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(b) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# [1, 2, [3, 4, 5]],受影响\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(c) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# [1, 2, [3, 4]],不受影响\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e重点:\u003c/strong\u003e 浅拷贝最怕“列表里面还有列表”这种嵌套可变对象。\u003c/p\u003e\n\u003chr\u003e\n\u003ch1 id=\"5-网络编程\"\u003e5. 网络编程\u003c/h1\u003e\u003ch2 id=\"5-1-网络编程三要素\"\u003e5.1 网络编程三要素\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e要素\u003c/th\u003e\n\u003cth\u003e作用\u003c/th\u003e\n\u003cth\u003e类比\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003eIP 地址\u003c/td\u003e\n\u003ctd\u003e找到哪台电脑\u003c/td\u003e\n\u003ctd\u003e家庭地址\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e端口\u003c/td\u003e\n\u003ctd\u003e找到电脑上的哪个程序\u003c/td\u003e\n\u003ctd\u003e门牌/窗口\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e协议\u003c/td\u003e\n\u003ctd\u003e通信规则\u003c/td\u003e\n\u003ctd\u003e双方都能听懂的语言\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e端口号:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e0~1023:知名端口。\u003c/li\u003e\n\u003cli\u003e1024~65535:动态端口,开发程序常用。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"5-2-tcp-协议\"\u003e5.2 TCP 协议\u003c/h2\u003e\u003cp\u003eTCP:传输控制协议,特点是\u003cstrong\u003e面向连接、可靠传输、基于字节流\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e通信流程:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e建立连接。\u003c/li\u003e\n\u003cli\u003e传输数据。\u003c/li\u003e\n\u003cli\u003e关闭连接。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e三次握手:建立连接。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e客户端请求连接。\u003c/li\u003e\n\u003cli\u003e服务端确认收到请求。\u003c/li\u003e\n\u003cli\u003e客户端再次确认,连接建立。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e四次挥手:断开连接。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eA 请求关闭。\u003c/li\u003e\n\u003cli\u003eB 确认 A 的关闭请求。\u003c/li\u003e\n\u003cli\u003eB 请求关闭。\u003c/li\u003e\n\u003cli\u003eA 确认 B 的关闭请求。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"5-3-socket\"\u003e5.3 socket\u003c/h2\u003e\u003cp\u003esocket 是进程间网络通信的工具。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20socket%0A%0Atcp_socket%20%3D%20socket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e socket\n\ntcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eAF_INET\u003c/code\u003e:IPv4。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eSOCK_STREAM\u003c/code\u003e:TCP。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e网络传输的是 \u003ccode\u003ebytes\u003c/code\u003e,字符串要编码/解码:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"s%20%3D%20%22%E4%BD%A0%E5%A5%BD%22%0Ab%20%3D%20s.encode(%22utf-8%22)%0As2%20%3D%20b.decode(%22utf-8%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003es = \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"你好\"\u003c/span\u003e\nb = s.encode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e)\ns2 = b.decode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"5-4-tcp-服务端流程\"\u003e5.4 TCP 服务端流程\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e创建 socket。\u003c/li\u003e\n\u003cli\u003e绑定 IP 和端口。\u003c/li\u003e\n\u003cli\u003e设置监听。\u003c/li\u003e\n\u003cli\u003e等待客户端连接。\u003c/li\u003e\n\u003cli\u003e接收/发送数据。\u003c/li\u003e\n\u003cli\u003e关闭连接 socket。\u003c/li\u003e\n\u003cli\u003e关闭服务端 socket。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20socket%0A%0Aserver%20%3D%20socket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)%0Aserver.setsockopt(socket.SOL_SOCKET%2C%20socket.SO_REUSEADDR%2C%20True)%0Aserver.bind((%22%22%2C%208888))%0Aserver.listen(128)%0A%0Aconn%2C%20addr%20%3D%20server.accept()%0Aprint(%22%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%9C%B0%E5%9D%80%EF%BC%9A%22%2C%20addr)%0A%0Adata%20%3D%20conn.recv(1024)%0Aprint(data.decode(%22utf-8%22))%0A%0Aconn.send(%22%E6%94%B6%E5%88%B0%22.encode(%22utf-8%22))%0A%0Aconn.close()%0Aserver.close()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e socket\n\nserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e)\nserver.bind((\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"\"\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e8888\u003c/span\u003e))\nserver.listen(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e128\u003c/span\u003e)\n\nconn, addr = server.accept()\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"客户端地址:\"\u003c/span\u003e, addr)\n\ndata = conn.recv(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1024\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(data.decode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\n\nconn.send(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"收到\"\u003c/span\u003e.encode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\n\nconn.close()\nserver.close()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"5-5-tcp-客户端流程\"\u003e5.5 TCP 客户端流程\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e创建 socket。\u003c/li\u003e\n\u003cli\u003e连接服务端。\u003c/li\u003e\n\u003cli\u003e发送/接收数据。\u003c/li\u003e\n\u003cli\u003e关闭 socket。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20socket%0A%0Aclient%20%3D%20socket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)%0Aclient.connect((%22127.0.0.1%22%2C%208888))%0A%0Aclient.send(%22hello%22.encode(%22utf-8%22))%0Adata%20%3D%20client.recv(1024)%0Aprint(data.decode(%22utf-8%22))%0A%0Aclient.close()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e socket\n\nclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nclient.connect((\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"127.0.0.1\"\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e8888\u003c/span\u003e))\n\nclient.send(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"hello\"\u003c/span\u003e.encode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\ndata = client.recv(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1024\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(data.decode(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"utf-8\"\u003c/span\u003e))\n\nclient.close()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e客户端连接的端口必须和服务端绑定的端口一致。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eaccept()\u003c/code\u003e 前的服务端 socket 是“被动套接字”,只负责接收连接。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eaccept()\u003c/code\u003e 返回的新 socket 才负责和具体客户端通信。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erecv()\u003c/code\u003e 是阻塞等待;客户端关闭后,服务端 \u003ccode\u003erecv()\u003c/code\u003e 可能返回长度为 0 的数据。\u003c/li\u003e\n\u003cli\u003e服务端重启端口没释放,可加:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"server.setsockopt(socket.SOL_SOCKET%2C%20socket.SO_REUSEADDR%2C%20True)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"6-进程\"\u003e6. 进程\u003c/h1\u003e\u003ch2 id=\"6-1-多任务-并发-并行\"\u003e6.1 多任务、并发、并行\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e概念\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e多任务\u003c/td\u003e\n\u003ctd\u003e同一时间段内执行多个任务,用户感觉像同时运行\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e并发\u003c/td\u003e\n\u003ctd\u003e单核 CPU 交替执行多个任务\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e并行\u003c/td\u003e\n\u003ctd\u003e多核 CPU 真正同时执行多个任务\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"6-2-进程概念\"\u003e6.2 进程概念\u003c/h2\u003e\u003cp\u003e进程是操作系统进行资源分配和调度运行的基本单位,也可理解为“正在运行的程序”。\u003c/p\u003e\n\u003cp\u003e特点:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一个程序运行后至少有一个主进程。\u003c/li\u003e\n\u003cli\u003e主进程可以创建子进程。\u003c/li\u003e\n\u003cli\u003e进程之间默认不共享全局变量。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"6-3-创建多进程\"\u003e6.3 创建多进程\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20multiprocessing%0A%0Adef%20task()%3A%0A%20%20%20%20print(%22%E4%BB%BB%E5%8A%A1%E6%89%A7%E8%A1%8C%22)%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20p%20%3D%20multiprocessing.Process(target%3Dtask)%0A%20%20%20%20p.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e multiprocessing\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003etask\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"任务执行\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e __name__ == \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"__main__\"\u003c/span\u003e:\n p = multiprocessing.Process(target=task)\n p.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e带参数:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20coding(num%2C%20name)%3A%0A%20%20%20%20for%20i%20in%20range(num)%3A%0A%20%20%20%20%20%20%20%20print(f%22%7Bname%7D%E5%86%99%E7%AC%AC%7Bi%7D%E8%A1%8C%E4%BB%A3%E7%A0%81%22)%0A%0Ap%20%3D%20multiprocessing.Process(target%3Dcoding%2C%20args%3D(3%2C%20%22%E5%B0%8F%E6%98%8E%22))%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ecoding\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003enum, name\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e i \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(num):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003ef\"\u003cspan class=\"hljs-subst\"\u003e{name}\u003c/span\u003e写第\u003cspan class=\"hljs-subst\"\u003e{i}\u003c/span\u003e行代码\"\u003c/span\u003e)\n\np = multiprocessing.Process(target=coding, args=(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e))\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20music(count%2C%20name)%3A%0A%20%20%20%20print(count%2C%20name)%0A%0Ap%20%3D%20multiprocessing.Process(target%3Dmusic%2C%20kwargs%3D%7B%22count%22%3A%203%2C%20%22name%22%3A%20%22%E5%B0%8F%E6%98%8E%22%7D)%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emusic\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ecount, name\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(count, name)\n\np = multiprocessing.Process(target=music, kwargs={\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"count\"\u003c/span\u003e: \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"name\"\u003c/span\u003e: \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e})\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"6-4-进程编号\"\u003e6.4 进程编号\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20os%0Aimport%20multiprocessing%0A%0Aprint(os.getpid())%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E5%BD%93%E5%89%8D%E8%BF%9B%E7%A8%8B%20ID%0Aprint(os.getppid())%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E7%88%B6%E8%BF%9B%E7%A8%8B%20ID%0Aprint(multiprocessing.current_process().pid)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e os\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e multiprocessing\n\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(os.getpid()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 当前进程 ID\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(os.getppid()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 父进程 ID\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(multiprocessing.current_process().pid)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"6-5-进程注意点\"\u003e6.5 进程注意点\u003c/h2\u003e\u003ch3 id=\"进程之间不共享全局变量\"\u003e进程之间不共享全局变量\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20multiprocessing%0A%0Amy_list%20%3D%20%5B%5D%0A%0Adef%20write_data()%3A%0A%20%20%20%20my_list.append(1)%0A%20%20%20%20print(%22write%3A%22%2C%20my_list)%0A%0Adef%20read_data()%3A%0A%20%20%20%20print(%22read%3A%22%2C%20my_list)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e multiprocessing\n\nmy_list = []\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ewrite_data\u003c/span\u003e():\n my_list.append(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e)\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"write:\"\u003c/span\u003e, my_list)\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eread_data\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"read:\"\u003c/span\u003e, my_list)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e子进程会复制主进程资源,名字相同但不是同一块内存。\u003c/p\u003e\n\u003ch3 id=\"主进程默认等待子进程结束\"\u003e主进程默认等待子进程结束\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"p%20%3D%20multiprocessing.Process(target%3Dtask)%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ep = multiprocessing.Process(target=task)\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e主进程结束前,通常会等子进程执行完。\u003c/p\u003e\n\u003cp\u003e不想等:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"p.daemon%20%3D%20True%20%20%20%23%20%E4%B8%BB%E8%BF%9B%E7%A8%8B%E7%BB%93%E6%9D%9F%EF%BC%8C%E5%AD%90%E8%BF%9B%E7%A8%8B%E8%B7%9F%E7%9D%80%E9%94%80%E6%AF%81%0Ap.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ep.daemon = \u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 主进程结束,子进程跟着销毁\u003c/span\u003e\np.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e或:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"p.terminate()%20%20%20%20%20%23%20%E6%89%8B%E5%8A%A8%E7%BB%88%E6%AD%A2%E5%AD%90%E8%BF%9B%E7%A8%8B%EF%BC%8C%E4%B8%8D%E5%A4%AA%E6%8E%A8%E8%8D%90\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ep.terminate() \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 手动终止子进程,不太推荐\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003chr\u003e\n\u003ch1 id=\"7-线程\"\u003e7. 线程\u003c/h1\u003e\u003ch2 id=\"7-1-线程概念\"\u003e7.1 线程概念\u003c/h2\u003e\u003cul\u003e\n\u003cli\u003e进程是资源分配的基本单位。\u003c/li\u003e\n\u003cli\u003e线程是 CPU 调度的基本单位。\u003c/li\u003e\n\u003cli\u003e一个进程至少有一个线程,默认叫主线程。\u003c/li\u003e\n\u003cli\u003e线程必须依附于进程存在。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"7-2-创建多线程\"\u003e7.2 创建多线程\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20threading%0A%0Adef%20task()%3A%0A%20%20%20%20print(%22%E7%BA%BF%E7%A8%8B%E4%BB%BB%E5%8A%A1%22)%0A%0Athread%20%3D%20threading.Thread(target%3Dtask)%0Athread.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e threading\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003etask\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"线程任务\"\u003c/span\u003e)\n\nthread = threading.Thread(target=task)\nthread.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e带参数:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"threading.Thread(target%3Dcoding%2C%20args%3D(3%2C%20%22%E5%B0%8F%E6%98%8E%22)).start()%0Athreading.Thread(target%3Dmusic%2C%20kwargs%3D%7B%22count%22%3A%203%2C%20%22name%22%3A%20%22%E5%B0%8F%E6%98%8E%22%7D).start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ethreading.Thread(target=coding, args=(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e)).start()\nthreading.Thread(target=music, kwargs={\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"count\"\u003c/span\u003e: \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e3\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"name\"\u003c/span\u003e: \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"小明\"\u003c/span\u003e}).start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"7-3-线程注意点\"\u003e7.3 线程注意点\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e线程执行顺序是无序的,由 CPU 调度决定。\u003c/li\u003e\n\u003cli\u003e主线程默认等待所有子线程执行完再结束。\u003c/li\u003e\n\u003cli\u003e线程之间共享全局变量。\u003c/li\u003e\n\u003cli\u003e共享全局变量可能出现数据安全问题。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e守护线程:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"thread%20%3D%20threading.Thread(target%3Dtask%2C%20daemon%3DTrue)%0Athread.start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ethread = threading.Thread(target=task, daemon=\u003cspan class=\"hljs-literal\" style=\"color:#569cd6;font-weight:600;\"\u003eTrue\u003c/span\u003e)\nthread.start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"7-4-线程共享全局变量\"\u003e7.4 线程共享全局变量\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20threading%0A%0Amy_list%20%3D%20%5B%5D%0A%0Adef%20write_data()%3A%0A%20%20%20%20my_list.append(1)%0A%0Athreading.Thread(target%3Dwrite_data).start()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e threading\n\nmy_list = []\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003ewrite_data\u003c/span\u003e():\n my_list.append(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e)\n\nthreading.Thread(target=write_data).start()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e同一进程内的多个线程共享全局变量,所以一个线程修改后,其他线程能看到。\u003c/p\u003e\n\u003ch2 id=\"7-5-数据安全与互斥锁\"\u003e7.5 数据安全与互斥锁\u003c/h2\u003e\u003cp\u003e多个线程同时修改同一个全局变量,可能导致结果错误。\u003c/p\u003e\n\u003cp\u003e互斥锁:同一时刻只允许一个线程操作共享数据。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20threading%0A%0Ag_num%20%3D%200%0Amutex%20%3D%20threading.Lock()%0A%0Adef%20add_num()%3A%0A%20%20%20%20global%20g_num%0A%20%20%20%20mutex.acquire()%0A%20%20%20%20for%20_%20in%20range(100000)%3A%0A%20%20%20%20%20%20%20%20g_num%20%2B%3D%201%0A%20%20%20%20mutex.release()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e threading\n\ng_num = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\nmutex = threading.Lock()\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_num\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eglobal\u003c/span\u003e g_num\n mutex.acquire()\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e _ \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e100000\u003c/span\u003e):\n g_num += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n mutex.release()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e更安全写法:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20add_num()%3A%0A%20%20%20%20global%20g_num%0A%20%20%20%20with%20mutex%3A%0A%20%20%20%20%20%20%20%20for%20_%20in%20range(100000)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20g_num%20%2B%3D%201\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eadd_num\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eglobal\u003c/span\u003e g_num\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ewith\u003c/span\u003e mutex:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e _ \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e100000\u003c/span\u003e):\n g_num += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e死锁:线程一直等对方释放锁,程序卡住。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e 上锁后必须释放锁,否则容易死锁。\u003c/p\u003e\n\u003ch2 id=\"7-6-进程-vs-线程\"\u003e7.6 进程 vs 线程\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e对比\u003c/th\u003e\n\u003cth\u003e进程\u003c/th\u003e\n\u003cth\u003e线程\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e单位\u003c/td\u003e\n\u003ctd\u003e资源分配基本单位\u003c/td\u003e\n\u003ctd\u003eCPU 调度基本单位\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e是否独立\u003c/td\u003e\n\u003ctd\u003e独立\u003c/td\u003e\n\u003ctd\u003e依附于进程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e全局变量\u003c/td\u003e\n\u003ctd\u003e默认不共享\u003c/td\u003e\n\u003ctd\u003e共享\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e开销\u003c/td\u003e\n\u003ctd\u003e大\u003c/td\u003e\n\u003ctd\u003e小\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e稳定性\u003c/td\u003e\n\u003ctd\u003e更强,一个进程挂了不一定影响其他进程\u003c/td\u003e\n\u003ctd\u003e一个线程异常可能影响整个进程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e多核利用\u003c/td\u003e\n\u003ctd\u003e可以更好利用多核\u003c/td\u003e\n\u003ctd\u003eCPython 中 CPU 密集型受 GIL 限制\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e按课件记:多进程资源开销大但稳定性强;多线程资源开销小但要注意共享数据安全。\u003c/p\u003e\n\u003chr\u003e\n\u003ch1 id=\"8-迭代器-生成器-property-正则表达式\"\u003e8. 迭代器、生成器、property、正则表达式\u003c/h1\u003e\u003ch2 id=\"8-1-迭代器\"\u003e8.1 迭代器\u003c/h2\u003e\u003cp\u003e迭代器是实现了 \u003ccode\u003e__iter__()\u003c/code\u003e 和 \u003ccode\u003e__next__()\u003c/code\u003e 的对象。\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20MyIterator(object)%3A%0A%20%20%20%20def%20__init__(self%2C%20start%2C%20end)%3A%0A%20%20%20%20%20%20%20%20self.current%20%3D%20start%0A%20%20%20%20%20%20%20%20self.end%20%3D%20end%0A%0A%20%20%20%20def%20__iter__(self)%3A%0A%20%20%20%20%20%20%20%20return%20self%0A%0A%20%20%20%20def%20__next__(self)%3A%0A%20%20%20%20%20%20%20%20if%20self.current%20%3E%20self.end%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20raise%20StopIteration%0A%20%20%20%20%20%20%20%20value%20%3D%20self.current%0A%20%20%20%20%20%20%20%20self.current%20%2B%3D%201%0A%20%20%20%20%20%20%20%20return%20value%0A%0Afor%20num%20in%20MyIterator(1%2C%205)%3A%0A%20%20%20%20print(num)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003eMyIterator\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, start, end\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current = start\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.end = end\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__iter__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__next__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current \u0026gt; \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.end:\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eraise\u003c/span\u003e StopIteration\n value = \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.current += \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e value\n\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e num \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e MyIterator(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e, \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(num)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e特点:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e手动管理状态。\u003c/li\u003e\n\u003cli\u003e可以用 \u003ccode\u003enext()\u003c/code\u003e 或 \u003ccode\u003efor\u003c/code\u003e 遍历。\u003c/li\u003e\n\u003cli\u003e惰性计算,适合大数据/流式数据。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"8-2-生成器\"\u003e8.2 生成器\u003c/h2\u003e\u003cp\u003e生成器是更简单的迭代器写法。\u003c/p\u003e\n\u003ch3 id=\"生成器推导式\"\u003e生成器推导式\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"g%20%3D%20(i%20*%202%20for%20i%20in%20range(5))%0Afor%20value%20in%20g%3A%0A%20%20%20%20print(value)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eg = (i * \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e i \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e5\u003c/span\u003e))\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e value \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e g:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(value)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e注意:小括号里是生成规则,不是一次性存好所有数据。\u003c/p\u003e\n\u003ch3 id=\"yield-生成器\"\u003eyield 生成器\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"def%20my_generator(n)%3A%0A%20%20%20%20for%20i%20in%20range(n)%3A%0A%20%20%20%20%20%20%20%20print(%22%E5%BC%80%E5%A7%8B%E7%94%9F%E6%88%90%22)%0A%20%20%20%20%20%20%20%20yield%20i%0A%20%20%20%20%20%20%20%20print(%22%E5%AE%8C%E6%88%90%E4%B8%80%E6%AC%A1%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003emy_generator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003en\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003efor\u003c/span\u003e i \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ein\u003c/span\u003e \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003erange\u003c/span\u003e(n):\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"开始生成\"\u003c/span\u003e)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eyield\u003c/span\u003e i\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"完成一次\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003eyield\u003c/code\u003e 作用:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e返回 \u003ccode\u003eyield\u003c/code\u003e 后面的值。\u003c/li\u003e\n\u003cli\u003e暂停函数执行,下次从暂停位置继续。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003ccode\u003efor\u003c/code\u003e 循环会自动处理 \u003ccode\u003eStopIteration\u003c/code\u003e,所以比手动 \u003ccode\u003enext()\u003c/code\u003e 更方便。\u003c/p\u003e\n\u003ch2 id=\"8-3-迭代器-vs-生成器\"\u003e8.3 迭代器 vs 生成器\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e对比\u003c/th\u003e\n\u003cth\u003e迭代器\u003c/th\u003e\n\u003cth\u003e生成器\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e实现方式\u003c/td\u003e\n\u003ctd\u003e手写 \u003ccode\u003e__iter__\u003c/code\u003e 和 \u003ccode\u003e__next__\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e使用 \u003ccode\u003eyield\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e状态管理\u003c/td\u003e\n\u003ctd\u003e自己管理\u003c/td\u003e\n\u003ctd\u003ePython 自动管理\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e代码量\u003c/td\u003e\n\u003ctd\u003e较多\u003c/td\u003e\n\u003ctd\u003e简洁\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e场景\u003c/td\u003e\n\u003ctd\u003e复杂迭代逻辑\u003c/td\u003e\n\u003ctd\u003e简洁生成数据、大数据按需生成\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"8-4-property-属性\"\u003e8.4 property 属性\u003c/h2\u003e\u003cp\u003e作用:把方法当成属性使用,简化调用,同时可控制读写逻辑。\u003c/p\u003e\n\u003ch3 id=\"装饰器方式\"\u003e装饰器方式\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%200%0A%0A%20%20%20%20%40property%0A%20%20%20%20def%20age(self)%3A%0A%20%20%20%20%20%20%20%20return%20self.__age%0A%0A%20%20%20%20%40age.setter%0A%20%20%20%20def%20age(self%2C%20new_age)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%20new_age%0A%0Ap%20%3D%20Person()%0Aprint(p.age)%0Ap.age%20%3D%2018\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @property\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eage\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age\n\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e @age.setter\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eage\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, new_age\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = new_age\n\np = Person()\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(p.age)\np.age = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e18\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch3 id=\"类属性方式\"\u003e类属性方式\u003c/h3\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"class%20Person(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%200%0A%0A%20%20%20%20def%20get_age(self)%3A%0A%20%20%20%20%20%20%20%20return%20self.__age%0A%0A%20%20%20%20def%20set_age(self%2C%20new_age)%3A%0A%20%20%20%20%20%20%20%20self.__age%20%3D%20new_age%0A%0A%20%20%20%20age%20%3D%20property(get_age%2C%20set_age)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003ePerson\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e0\u003c/span\u003e\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eget_age\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age\n\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eset_age\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself, new_age\u003c/span\u003e):\n \u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__age = new_age\n\n age = \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eproperty\u003c/span\u003e(get_age, set_age)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"8-5-正则表达式与-re-模块\"\u003e8.5 正则表达式与 re 模块\u003c/h2\u003e\u003cp\u003e正则表达式:用特殊符号描述字符串匹配规则。\u003c/p\u003e\n\u003cp\u003e常见作用:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e数据验证:手机号、邮箱、IP。\u003c/li\u003e\n\u003cli\u003e数据检索:爬虫提取内容。\u003c/li\u003e\n\u003cli\u003e数据替换:敏感词过滤。\u003c/li\u003e\n\u003cli\u003e数据隐藏:手机号脱敏。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003ere 三步:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20re%0A%0Aresult%20%3D%20re.match(pattern%2C%20string)%0Aif%20result%3A%0A%20%20%20%20print(result.group())\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e re\n\nresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(pattern, string)\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e result:\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group())\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"8-6-match-search-sub\"\u003e8.6 match、search、sub\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"re.match(pattern%2C%20string)%20%20%20%20%23%20%E4%BB%8E%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%BC%80%E5%A4%B4%E5%8C%B9%E9%85%8D%0Are.search(pattern%2C%20string)%20%20%20%23%20%E6%89%AB%E6%8F%8F%E6%95%B4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E8%BF%94%E5%9B%9E%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%8C%B9%E9%85%8D%0Are.sub(pattern%2C%20repl%2C%20string)%20%23%20%E6%9B%BF%E6%8D%A2\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ere.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(pattern, string) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 从字符串开头匹配\u003c/span\u003e\nre.search(pattern, string) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 扫描整个字符串,返回第一个匹配\u003c/span\u003e\nre.sub(pattern, repl, string) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 替换\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e例子:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"import%20re%0A%0Aresult%20%3D%20re.search(r%22%5Cd.*%22%2C%20%22city%3A1beijing2.shanghai%22)%0Aprint(result.group())%20%20%23%201beijing2.shanghai\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eimport\u003c/span\u003e re\n\nresult = re.search(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"\\d.*\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"city:1beijing2.shanghai\"\u003c/span\u003e)\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 1beijing2.shanghai\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"8-7-单字符匹配\"\u003e8.7 单字符匹配\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e符号\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e.\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e任意一个字符,除了换行符\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e[abc]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配 a/b/c 中任意一个\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e[a-z]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配小写字母\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\d\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e数字,等价于 \u003ccode\u003e[0-9]\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\D\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e非数字\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\s\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e空白字符,空格、tab 等\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\S\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e非空白\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\w\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e字母、数字、下划线、汉字\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\\W\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e非 \u003ccode\u003e\\w\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003ch2 id=\"8-8-多字符匹配\"\u003e8.8 多字符匹配\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e符号\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 0 次或多次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e+\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 1 次或多次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e?\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 0 次或 1 次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e{m}\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 m 次\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e{m,n}\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e前一个字符出现 m 到 n 次\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003e易错点:\u003c/strong\u003e \u003ccode\u003e{2,5}\u003c/code\u003e 逗号后不要写空格。\u003c/p\u003e\n\u003ch2 id=\"8-9-开头-结尾-取反\"\u003e8.9 开头、结尾、取反\u003c/h2\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e符号\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e^\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配字符串开头\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e$\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配字符串结尾\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e[^abc]\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e匹配除了 a/b/c 之外的字符\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"re.match(r%22%5E%5Cd.*%5Cd%24%22%2C%20%2211itcast22%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003ere.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"^\\d.*\\d$\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"11itcast22\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e表示:以数字开头,以数字结尾,中间任意内容。\u003c/p\u003e\n\u003ch2 id=\"8-10-分组\"\u003e8.10 分组\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"result%20%3D%20re.match(r%22(qq)%3A(%5B1-9%5D%5Cd%7B4%2C11%7D)%22%2C%20%22qq%3A10567%22)%0A%0Aprint(result.group())%20%20%20%23%20%E5%85%A8%E9%83%A8%EF%BC%9Aqq%3A10567%0Aprint(result.group(1))%20%20%23%20qq%0Aprint(result.group(2))%20%20%23%2010567\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"(qq):([1-9]\\d{4,11})\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"qq:10567\"\u003c/span\u003e)\n\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group()) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 全部:qq:10567\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e)) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# qq\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(result.group(\u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e2\u003c/span\u003e)) \u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 10567\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e邮箱例子:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"result%20%3D%20re.match(r%22%5Ba-zA-Z0-9_%5D%7B4%2C20%7D%40(163%7C126%7Cqq)%5C.com%22%2C%20%22hello%40qq.com%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"[a-zA-Z0-9_]{4,20}@(163|126|qq)\\.com\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"hello@qq.com\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e分组引用:\u003c/p\u003e\n\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"result%20%3D%20re.match(r%22%3C(%5Ba-zA-Z1-6%5D%7B1%2C10%7D)%3E.*%3C%2F%5C1%3E%22%2C%20%22%3Chtml%3Ehh%3C%2Fhtml%3E%22)\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003eresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(\u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003er\"\u0026lt;([a-zA-Z1-6]{1,10})\u0026gt;.*\u0026lt;/\\1\u0026gt;\"\u003c/span\u003e, \u003cspan class=\"hljs-string\" style=\"color:#ce9178;\"\u003e\"\u0026lt;html\u0026gt;hh\u0026lt;/html\u0026gt;\"\u003c/span\u003e)\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003cp\u003e\u003ccode\u003e\\1\u003c/code\u003e 表示引用第一个分组匹配到的内容,保证前后标签一致。\u003c/p\u003e\n\u003chr\u003e\n\u003ch1 id=\"9-最后速记清单\"\u003e9. 最后速记清单\u003c/h1\u003e\u003ch2 id=\"9-1-必背语法模板\"\u003e9.1 必背语法模板\u003c/h2\u003e\u003cdiv class=\"code-block-wrapper\" data-code-rendered=\"true\"\u003e\n \u003cdiv class=\"code-block-header\"\u003e\n \u003cspan class=\"code-lang\"\u003epython\u003c/span\u003e\n \u003cbutton class=\"code-copy-btn\" data-code=\"%23%20%E7%B1%BB%0Aclass%20%E7%B1%BB%E5%90%8D(object)%3A%0A%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20pass%0A%0A%23%20%E7%BB%A7%E6%89%BF%0Aclass%20%E5%AD%90%E7%B1%BB(%E7%88%B6%E7%B1%BB)%3A%0A%20%20%20%20pass%0A%0A%23%20%E8%B0%83%E7%88%B6%E7%B1%BB%0Asuper().%E6%96%B9%E6%B3%95%E5%90%8D()%0A%0A%23%20%E7%A7%81%E6%9C%89%E5%B1%9E%E6%80%A7%0Aself.__%E5%B1%9E%E6%80%A7%E5%90%8D%20%3D%20%E5%80%BC%0A%0A%23%20%E7%B1%BB%E6%96%B9%E6%B3%95%0A%40classmethod%0Adef%20%E6%96%B9%E6%B3%95%E5%90%8D(cls)%3A%0A%20%20%20%20pass%0A%0A%23%20%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95%0A%40staticmethod%0Adef%20%E6%96%B9%E6%B3%95%E5%90%8D()%3A%0A%20%20%20%20pass%0A%0A%23%20%E9%97%AD%E5%8C%85%0Adef%20outer()%3A%0A%20%20%20%20x%20%3D%201%0A%20%20%20%20def%20inner()%3A%0A%20%20%20%20%20%20%20%20print(x)%0A%20%20%20%20return%20inner%0A%0A%23%20%E9%80%9A%E7%94%A8%E8%A3%85%E9%A5%B0%E5%99%A8%0Adef%20decorator(fn)%3A%0A%20%20%20%20def%20inner(*args%2C%20**kwargs)%3A%0A%20%20%20%20%20%20%20%20return%20fn(*args%2C%20**kwargs)%0A%20%20%20%20return%20inner%0A%0A%23%20%E8%BF%9B%E7%A8%8B%0Amultiprocessing.Process(target%3D%E4%BB%BB%E5%8A%A1%E5%90%8D).start()%0A%0A%23%20%E7%BA%BF%E7%A8%8B%0Athreading.Thread(target%3D%E4%BB%BB%E5%8A%A1%E5%90%8D).start()%0A%0A%23%20socket%0Asocket.socket(socket.AF_INET%2C%20socket.SOCK_STREAM)%0A%0A%23%20%E6%AD%A3%E5%88%99%0Aresult%20%3D%20re.match(pattern%2C%20string)%0Aif%20result%3A%0A%20%20%20%20result.group()\"\u003e复制\u003c/button\u003e\n \u003c/div\u003e\n \u003cpre class=\"code-block\"\u003e\u003ccode class=\"hljs language-python\"\u003e\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003e类名\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003eobject\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003eself\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 继承\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eclass\u003c/span\u003e \u003cspan class=\"hljs-title class_\" style=\"color:#dcdcaa;\"\u003e子类\u003c/span\u003e(\u003cspan class=\"hljs-title class_ inherited__\" style=\"color:#dcdcaa;\"\u003e父类\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 调父类\u003c/span\u003e\n\u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003esuper\u003c/span\u003e().方法名()\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 私有属性\u003c/span\u003e\n\u003cspan class=\"hljs-variable language_\" style=\"color:#9cdcfe;\"\u003eself\u003c/span\u003e.__属性名 = 值\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 类方法\u003c/span\u003e\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@classmethod\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e方法名\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003ecls\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 静态方法\u003c/span\u003e\n\u003cspan class=\"hljs-meta\" style=\"color:#c586c0;\"\u003e@staticmethod\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003e方法名\u003c/span\u003e():\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003epass\u003c/span\u003e\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 闭包\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003eouter\u003c/span\u003e():\n x = \u003cspan class=\"hljs-number\" style=\"color:#b8d7a3;\"\u003e1\u003c/span\u003e\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e():\n \u003cspan class=\"hljs-built_in\" style=\"color:#4ec9b0;font-weight:600;\"\u003eprint\u003c/span\u003e(x)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 通用装饰器\u003c/span\u003e\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003edecorator\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003efn\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003edef\u003c/span\u003e \u003cspan class=\"hljs-title function_\" style=\"color:#dcdcaa;\"\u003einner\u003c/span\u003e(\u003cspan class=\"hljs-params\" style=\"color:#dcdcaa;\"\u003e*args, **kwargs\u003c/span\u003e):\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e fn(*args, **kwargs)\n \u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ereturn\u003c/span\u003e inner\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 进程\u003c/span\u003e\nmultiprocessing.Process(target=任务名).start()\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 线程\u003c/span\u003e\nthreading.Thread(target=任务名).start()\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# socket\u003c/span\u003e\nsocket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\n\u003cspan class=\"hljs-comment\" style=\"color:#6a9955;font-style:italic;\"\u003e# 正则\u003c/span\u003e\nresult = re.\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003ematch\u003c/span\u003e(pattern, string)\n\u003cspan class=\"hljs-keyword\" style=\"color:#569cd6;font-weight:600;\"\u003eif\u003c/span\u003e result:\n result.group()\u003c/code\u003e\u003c/pre\u003e\n \u003c/div\u003e\u003ch2 id=\"9-2-高频易错点\"\u003e9.2 高频易错点\u003c/h2\u003e\u003col\u003e\n\u003cli\u003e\u003ccode\u003eself\u003c/code\u003e 不是随便写的,它代表当前对象。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e__init__\u003c/code\u003e 创建对象时自动执行,不是手动调用的普通函数。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e__str__\u003c/code\u003e 必须 \u003ccode\u003ereturn\u003c/code\u003e 字符串,不能直接 \u003ccode\u003eprint\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e子类重写父类方法后,优先调用子类方法。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esuper().方法()\u003c/code\u003e 不写 \u003ccode\u003eself\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e私有属性 \u003ccode\u003e__xxx\u003c/code\u003e 类外不能直接访问,应写 \u003ccode\u003eget_xxx\u003c/code\u003e / \u003ccode\u003eset_xxx\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e装饰器如果原函数有返回值,内部函数也必须 \u003ccode\u003ereturn\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e多个装饰器:装饰时由内到外,执行时由外到内。\u003c/li\u003e\n\u003cli\u003e浅拷贝遇到嵌套可变对象,内层仍然共享。\u003c/li\u003e\n\u003cli\u003eTCP 客户端连接端口必须和服务端绑定端口一致。\u003c/li\u003e\n\u003cli\u003e进程不共享全局变量,线程共享全局变量。\u003c/li\u003e\n\u003cli\u003e线程共享数据要加锁,加锁后必须释放锁。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ere.match()\u003c/code\u003e 从开头匹配;想从中间找用 \u003ccode\u003ere.search()\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e正则里 \u003ccode\u003e.\u003c/code\u003e 想表示真正的小数点,要写 \u003ccode\u003e\\.\u003c/code\u003e 或使用原始字符串 \u003ccode\u003er\"\\.\"\u003c/code\u003e。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"9-3-用一句话串起来\"\u003e9.3 用一句话串起来\u003c/h2\u003e\u003cp\u003ePython 高级这一组课的主线是:先用\u003cstrong\u003e面向对象\u003c/strong\u003e把现实事物抽象成类和对象,再用\u003cstrong\u003e继承、封装、多态\u003c/strong\u003e提高代码复用和扩展性;遇到函数增强用\u003cstrong\u003e闭包和装饰器\u003c/strong\u003e,遇到对象复制要区分\u003cstrong\u003e浅拷贝和深拷贝\u003c/strong\u003e;做网络通信要掌握 \u003cstrong\u003eIP、端口、协议、socket、TCP\u003c/strong\u003e;做多任务要区分\u003cstrong\u003e进程和线程\u003c/strong\u003e;处理大数据遍历用\u003cstrong\u003e迭代器/生成器\u003c/strong\u003e;处理字符串规则匹配用\u003cstrong\u003e正则表达式\u003c/strong\u003e。\u003c/p\u003e\n","toc":[{"level":1,"text":"Python 高级阶段快速复习","id":"python-高级阶段快速复习"},{"level":2,"text":"0. 总复习路线","id":"0-总复习路线"},{"level":1,"text":"1. 面向对象基础","id":"1-面向对象基础"},{"level":2,"text":"1.1 面向过程 vs 面向对象","id":"1-1-面向过程-vs-面向对象"},{"level":2,"text":"1.2 三大特性","id":"1-2-三大特性"},{"level":2,"text":"1.3 类、对象、self","id":"1-3-类-对象-self"},{"level":2,"text":"1.4 对象属性","id":"1-4-对象属性"},{"level":2,"text":"1.5 魔法方法","id":"1-5-魔法方法"},{"level":2,"text":"1.6 综合小案例思路:烤地瓜","id":"1-6-综合小案例思路-烤地瓜"},{"level":1,"text":"2. 面向对象高级","id":"2-面向对象高级"},{"level":2,"text":"2.1 类的三种写法","id":"2-1-类的三种写法"},{"level":2,"text":"2.2 继承","id":"2-2-继承"},{"level":2,"text":"2.3 单继承与多继承","id":"2-3-单继承与多继承"},{"level":2,"text":"2.4 重写与调用父类方法","id":"2-4-重写与调用父类方法"},{"level":2,"text":"2.5 多层继承","id":"2-5-多层继承"},{"level":2,"text":"2.6 封装与私有属性","id":"2-6-封装与私有属性"},{"level":2,"text":"2.7 多态","id":"2-7-多态"},{"level":2,"text":"2.8 抽象类/接口思想","id":"2-8-抽象类-接口思想"},{"level":2,"text":"2.9 类属性、类方法、静态方法","id":"2-9-类属性-类方法-静态方法"},{"level":3,"text":"对象属性","id":"对象属性"},{"level":3,"text":"类属性","id":"类属性"},{"level":3,"text":"类方法","id":"类方法"},{"level":3,"text":"静态方法","id":"静态方法"},{"level":1,"text":"3. 学生管理系统综合案例","id":"3-学生管理系统综合案例"},{"level":2,"text":"3.1 项目拆分","id":"3-1-项目拆分"},{"level":2,"text":"3.2 Student 类","id":"3-2-student-类"},{"level":2,"text":"3.3 管理系统核心属性","id":"3-3-管理系统核心属性"},{"level":2,"text":"3.4 主循环框架","id":"3-4-主循环框架"},{"level":2,"text":"3.5 增删改查思路","id":"3-5-增删改查思路"},{"level":3,"text":"添加","id":"添加"},{"level":3,"text":"删除","id":"删除"},{"level":3,"text":"修改","id":"修改"},{"level":3,"text":"查询","id":"查询"},{"level":3,"text":"显示全部","id":"显示全部"},{"level":2,"text":"3.6 保存与加载","id":"3-6-保存与加载"},{"level":2,"text":"3.7 main.py","id":"3-7-main-py"},{"level":1,"text":"4. 闭包、装饰器、深浅拷贝","id":"4-闭包-装饰器-深浅拷贝"},{"level":2,"text":"4.1 闭包","id":"4-1-闭包"},{"level":2,"text":"4.2 nonlocal","id":"4-2-nonlocal"},{"level":2,"text":"4.3 装饰器","id":"4-3-装饰器"},{"level":2,"text":"4.4 通用装饰器模板","id":"4-4-通用装饰器模板"},{"level":2,"text":"4.5 多个装饰器","id":"4-5-多个装饰器"},{"level":2,"text":"4.6 带参数的装饰器","id":"4-6-带参数的装饰器"},{"level":2,"text":"4.7 浅拷贝与深拷贝","id":"4-7-浅拷贝与深拷贝"},{"level":1,"text":"5. 网络编程","id":"5-网络编程"},{"level":2,"text":"5.1 网络编程三要素","id":"5-1-网络编程三要素"},{"level":2,"text":"5.2 TCP 协议","id":"5-2-tcp-协议"},{"level":2,"text":"5.3 socket","id":"5-3-socket"},{"level":2,"text":"5.4 TCP 服务端流程","id":"5-4-tcp-服务端流程"},{"level":2,"text":"5.5 TCP 客户端流程","id":"5-5-tcp-客户端流程"},{"level":1,"text":"6. 进程","id":"6-进程"},{"level":2,"text":"6.1 多任务、并发、并行","id":"6-1-多任务-并发-并行"},{"level":2,"text":"6.2 进程概念","id":"6-2-进程概念"},{"level":2,"text":"6.3 创建多进程","id":"6-3-创建多进程"},{"level":2,"text":"6.4 进程编号","id":"6-4-进程编号"},{"level":2,"text":"6.5 进程注意点","id":"6-5-进程注意点"},{"level":3,"text":"进程之间不共享全局变量","id":"进程之间不共享全局变量"},{"level":3,"text":"主进程默认等待子进程结束","id":"主进程默认等待子进程结束"},{"level":1,"text":"7. 线程","id":"7-线程"},{"level":2,"text":"7.1 线程概念","id":"7-1-线程概念"},{"level":2,"text":"7.2 创建多线程","id":"7-2-创建多线程"},{"level":2,"text":"7.3 线程注意点","id":"7-3-线程注意点"},{"level":2,"text":"7.4 线程共享全局变量","id":"7-4-线程共享全局变量"},{"level":2,"text":"7.5 数据安全与互斥锁","id":"7-5-数据安全与互斥锁"},{"level":2,"text":"7.6 进程 vs 线程","id":"7-6-进程-vs-线程"},{"level":1,"text":"8. 迭代器、生成器、property、正则表达式","id":"8-迭代器-生成器-property-正则表达式"},{"level":2,"text":"8.1 迭代器","id":"8-1-迭代器"},{"level":2,"text":"8.2 生成器","id":"8-2-生成器"},{"level":3,"text":"生成器推导式","id":"生成器推导式"},{"level":3,"text":"yield 生成器","id":"yield-生成器"},{"level":2,"text":"8.3 迭代器 vs 生成器","id":"8-3-迭代器-vs-生成器"},{"level":2,"text":"8.4 property 属性","id":"8-4-property-属性"},{"level":3,"text":"装饰器方式","id":"装饰器方式"},{"level":3,"text":"类属性方式","id":"类属性方式"},{"level":2,"text":"8.5 正则表达式与 re 模块","id":"8-5-正则表达式与-re-模块"},{"level":2,"text":"8.6 match、search、sub","id":"8-6-match-search-sub"},{"level":2,"text":"8.7 单字符匹配","id":"8-7-单字符匹配"},{"level":2,"text":"8.8 多字符匹配","id":"8-8-多字符匹配"},{"level":2,"text":"8.9 开头、结尾、取反","id":"8-9-开头-结尾-取反"},{"level":2,"text":"8.10 分组","id":"8-10-分组"},{"level":1,"text":"9. 最后速记清单","id":"9-最后速记清单"},{"level":2,"text":"9.1 必背语法模板","id":"9-1-必背语法模板"},{"level":2,"text":"9.2 高频易错点","id":"9-2-高频易错点"},{"level":2,"text":"9.3 用一句话串起来","id":"9-3-用一句话串起来"}],"history":[]}},"postRelatedBySlug":{"Python-高级阶段快速复习":{"posts":[{"id":9,"title":"Linux 快速复习笔记(简练翔实版)","slug":"Linux-快速复习笔记-简练翔实版","excerpt":"Linux 快速复习笔记(简练翔实版) 适合:考前快速过一遍、上机前查命令、把课件知识压缩成能背能敲的版本。 复习顺序:先懂 Linux 是什么 → 再会路径和命令 → 再会用户权限 → 最后掌握实用操作。 --- 0. 一句话总览 Linux 学习核心不是背概念,而是掌握: --- 第一章 初识 Linux 1. 操作系统是什么 计算机由两部分组成: | 组成 | 作用 | |--...","cover_image":"","published_at":"2026-05-05T13:29:27.500Z","first_published_at":"2026-05-05T09:11:17.730Z","cover_image_sources":null},{"id":8,"title":"MySQL 快速复习版","slug":"MySQL-快速复习版","excerpt":"MySQL 快速复习版 用途:考前速看、面试前回顾、写 SQL 前查模板。 风格:只保留高频概念、常用语法、易错点和面试表达。 范围:MySQL 基础篇、进阶篇、运维篇。 --- 0. 总复习路线 MySQL 可以按三层记: 最重要的一条主线: --- 第一部分:基础 SQL 必会 --- 1. 数据库基本概念 | 名称 | 含义 | 记忆 | |---|---|---| | ...","cover_image":null,"published_at":"2026-05-05T09:09:56.131Z","first_published_at":"2026-05-05T09:09:56.131Z","cover_image_sources":null}]}},"series":{"series":[]}},"generatedAt":1779631887795}