
九、面向对象编程
1. 类与对象
类是对象的模板,对象是类的实例。
python
# 定义一个Person类
class Person:
pass # pass表示空语句,用于占位
# 创建Person类的对象(实例)
p1 = Person()
p2 = Person()
# 查看对象类型
print(type(p1)) # 输出:<class '__main__.Person'>
print(p1 is p2) # 输出:False,p1和p2是不同的对象
2. 属性与方法
类包含属性(数据)和方法(操作数据的函数)。
python
class Person:
# 类属性:所有实例共享的属性
species = 'human' # 人类的物种都是'human'
# 初始化方法:创建对象时自动调用,用于初始化实例属性
def __init__(self, name, age):
self.name = name # 实例属性:每个对象独有的属性
self.age = age
# 实例方法:第一个参数必须是self,代表当前实例
def introduce(self):
# 通过self访问实例属性和类属性
return f"我叫{self.name},今年{self.age}岁,是{self.species}。"
# 类方法:用@classmethod装饰,第一个参数是cls,代表当前类
@classmethod
def get_species(cls):
return f"物种:{cls.species}"
# 静态方法:用@staticmethod装饰,无默认参数,与类和实例关联较弱
@staticmethod
def is_adult(age):
# 判断年龄是否成年,不依赖类或实例的属性
return age >= 18
# 创建对象时传入初始化参数
person1 = Person("张三", 20)
# 调用实例方法
print(person1.introduce()) # 输出:我叫张三,今年20岁,是human。
# 调用类方法(可通过类或实例调用)
print(Person.get_species()) # 输出:物种:human
print(person1.get_species()) # 输出:物种:human
# 调用静态方法(可通过类或实例调用)
print(Person.is_adult(17)) # 输出:False
print(person1.is_adult(20)) # 输出:True
3. 继承
子类继承父类的属性和方法,并可扩展或重写。
python
# 父类Person(同上,此处简化)
class Person:
species = 'human'
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return f"我叫{self.name},今年{self.age}岁。"
# 子类Student继承自Person
class Student(Person):
# 重写初始化方法
def __init__(self, name, age, grade):
# 调用父类的初始化方法
super().__init__(name, age)
self.grade = grade # 新增子类独有的属性
# 重写父类的introduce方法
def introduce(self):
# 先调用父类的introduce方法,再添加子类信息
parent_intro = super().introduce()
return f"{parent_intro}我在读{self.grade}年级。"
# 子类新增方法
def study(self):
return f"{self.name}正在学习。"
# 创建子类对象
student1 = Student("李四", 15, 9)
# 调用重写后的方法
print(student1.introduce()) # 输出:我叫李四,今年15岁。我在读9年级。
# 调用子类新增方法
print(student1.study()) # 输出:李四正在学习。
# 访问继承的类属性
print(student1.species) # 输出:human
4. 封装
通过私有属性限制直接访问,通过方法间接操作。
python
class BankAccount:
def __init__(self, balance=0):
self.__balance = balance # 私有属性:用双下划线开头
# 提供方法获取私有属性值
def get_balance(self):
return self.__balance
# 提供方法修改私有属性
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return "存款成功"
else:
return "存款金额必须为正数"
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
return "取款成功"
else:
return "取款金额无效"
account = BankAccount(1000)
# 无法直接访问私有属性
# print(account.__balance) # 报错:AttributeError: 'BankAccount' object has no attribute '__balance'
# 通过方法访问和修改
print(account.get_balance()) # 输出:1000
print(account.deposit(500)) # 输出:存款成功
print(account.get_balance()) # 输出:1500
print(account.withdraw(300)) # 输出:取款成功
print(account.get_balance()) # 输出:1200
5. 多态
不同对象对同一方法有不同实现。
ruby
# 父类
class Animal:
def make_sound(self):
pass # 父类方法未具体实现
# 子类1
class Dog(Animal):
def make_sound(self):
return "汪汪汪"
# 子类2
class Cat(Animal):
def make_sound(self):
return "喵喵喵"
# 子类3
class Duck(Animal):
def make_sound(self):
return "嘎嘎嘎"
# 统一接口:接收Animal类型的对象
def animal_sound(animal):
return animal.make_sound()
# 创建不同子类的对象
dog = Dog()
cat = Cat()
duck = Duck()
# 同一方法调用,不同对象有不同结果
print(animal_sound(dog)) # 输出:汪汪汪
print(animal_sound(cat)) # 输出:喵喵喵
print(animal_sound(duck)) # 输出:嘎嘎嘎
十、异常处理
1. try-except 语句
捕获并处理指定异常。
python
# 示例1:捕获特定异常
try:
num = int(input("请输入一个整数:"))
result = 10 / num
print(f"10除以{num}的结果是:{result}")
except ZeroDivisionError:
# 处理除零异常
print("错误:除数不能为0")
except ValueError:
# 处理值错误(输入无法转为整数)
print("错误:请输入有效的整数")
# 示例2:捕获所有异常(不推荐,难以定位问题)
try:
list1 = [1, 2, 3]
print(list1[5]) # 索引越界
except:
print("发生了未知错误")
2. try-except-else 语句
无异常时执行 else 块。
python
try:
a = int(input("请输入第一个数:"))
b = int(input("请输入第二个数:"))
result = a / b
except ZeroDivisionError:
print("除数不能为0")
except ValueError:
print("请输入有效的数字")
else:
# 当try块中无异常时执行
print(f"{a}除以{b}的结果是:{result}")
3. try-finally 语句
无论是否异常,finally 块都会执行。
python
file = None
try:
file = open("test.txt", "r")
content = file.read()
print(content)
except FileNotFoundError:
print("文件不存在")
finally:
# 无论是否发生异常,都确保文件关闭
if file:
file.close()
print("文件已关闭")
4. 自定义异常
创建并使用自定义异常类。
python
# 定义自定义异常类,继承自Exception
class ScoreError(Exception):
def __init__(self, message):
self.message = message
def check_score(score):
if not (0 <= score <= 100):
# 抛出自定义异常
raise ScoreError(f"分数{score}无效,必须在0-100之间")
else:
print(f"分数{score}有效")
try:
check_score(105)
except ScoreError as e:
# 捕获并处理自定义异常
print(e.message) # 输出:分数105无效,必须在0-100之间
十一、正则表达式
1. re 模块常用函数
python
import re
# 1. re.match:从字符串开头匹配
# 匹配以"Hello"开头的字符串
result = re.match(r"Hello", "Hello, World!")
if result:
print("匹配成功:", result.group()) # 输出:匹配成功: Hello
else:
print("匹配失败")
# 2. re.search:在整个字符串中搜索第一个匹配
# 搜索字符串中的数字
result = re.search(r"\d+", "年龄是25岁,身高175cm")
if result:
print("找到的第一个数字:", result.group()) # 输出:找到的第一个数字: 25
# 3. re.findall:找出所有匹配的子串
# 找出所有数字
numbers = re.findall(r"\d+", "年龄是25岁,身高175cm,体重65kg")
print("所有数字:", numbers) # 输出:所有数字: ['25', '175', '65']
# 4. re.sub:替换匹配的子串
# 将所有数字替换为"*"
text = "密码是123456,验证码是7890"
new_text = re.sub(r"\d+", "*", text)
print("替换后:", new_text) # 输出:替换后: 密码是*,验证码是*
2. 常用元字符示例
python
import re
# . 匹配任意单个字符(除换行)
print(re.findall(r"a.b", "acb aab a_b a\nb")) # 输出:['acb', 'aab', 'a_b']
# * 匹配前面字符0次或多次
print(re.findall(r"ab*c", "ac abc abbc abbbc")) # 输出:['ac', 'abc', 'abbc', 'abbbc']
# + 匹配前面字符1次或多次
print(re.findall(r"ab+c", "ac abc abbc")) # 输出:['abc', 'abbc']
# ? 匹配前面字符0次或1次
print(re.findall(r"ab?c", "ac abc abbc")) # 输出:['ac', 'abc']
# ^ 匹配字符串开头
print(re.findall(r"^hello", "hello world hello")) # 输出:['hello']
# $ 匹配字符串结尾
print(re.findall(r"world$", "hello world")) # 输出:['world']
# [] 匹配括号中任意一个字符
print(re.findall(r"[abc]", "a1b2c3d4")) # 输出:['a', 'b', 'c']
# () 分组
match = re.match(r"(\d{3})-(\d{4})", "123-4567")
if match:
print("完整匹配:", match.group()) # 输出:123-4567
print("第一组:", match.group(1)) # 输出:123
print("第二组:", match.group(2)) # 输出:4567
十二、迭代器与生成器
1. 迭代器
可被 next () 调用并返回下一个值的对象。
python
# 可迭代对象(列表)转换为迭代器
list1 = [10, 20, 30, 40]
iterator = iter(list1)
# 用next()获取下一个值
print(next(iterator)) # 输出:10
print(next(iterator)) # 输出:20
print(next(iterator)) # 输出:30
print(next(iterator)) # 输出:40
# print(next(iterator)) # 无更多值,抛出StopIteration异常
# 迭代器用于for循环(自动处理StopIteration)
iterator2 = iter(list1)
for item in iterator2:
print(item, end=" ") # 输出:10 20 30 40
print()
2. 生成器
通过 yield 创建的特殊迭代器。
python
# 生成器函数:包含yield语句
def number_generator(n):
for i in range(n):
yield i # 返回值并暂停,下次调用从这里继续
print(f"生成完{i}后继续执行")
# 创建生成器对象
generator = number_generator(3)
# 第一次调用next()
print(next(generator)) # 输出:0
# 第二次调用next()
print(next(generator)) # 先输出"生成完0后继续执行",再输出1
# 第三次调用next()
print(next(generator)) # 先输出"生成完1后继续执行",再输出2
# 第四次调用next()会抛出StopIteration
# 生成器表达式:类似列表推导式,用()表示
gen_expr = (x * 2 for x in range(3))
print(list(gen_expr)) # 输出:[0, 2, 4]
十三、并发编程基础
1. 线程
轻量级,共享进程资源。
python
import threading
import time
# 定义线程要执行的函数
def print_numbers(name, delay):
for i in range(5):
time.sleep(delay) # 暂停指定时间
print(f"线程{name}:{i}")
# 创建线程对象
thread1 = threading.Thread(target=print_numbers, args=("A", 0.5))
thread2 = threading.Thread(target=print_numbers, args=("B", 0.8))
# 启动线程
thread1.start()
thread2.start()
# 等待线程结束
thread1.join()
thread2.join()
print("所有线程执行完毕")
2. 进程
独立内存空间,适合 CPU 密集型任务。
python
import multiprocessing
import time
def process_task(name, delay):
for i in range(3):
time.sleep(delay)
print(f"进程{name}:{i}")
# 在Windows系统中,进程创建需放在if __name__ == '__main__':下
if __name__ == '__main__':
# 创建进程对象
process1 = multiprocessing.Process(target=process_task, args=("X", 1))
process2 = multiprocessing.Process(target=process_task, args=("Y", 1.5))
# 启动进程
process1.start()
process2.start()
# 等待进程结束
process1.join()
process2.join()
print("所有进程执行完毕")
3. 协程
轻量级,适合 I/O 密集型任务。
python
import asyncio
import time
# 定义协程函数(用async修饰)
async def async_task(name, delay):
for i in range(3):
await asyncio.sleep(delay) # 等待(非阻塞)
print(f"协程{name}:{i}")
# 主协程
async def main():
# 创建协程对象
task1 = async_task("1", 1)
task2 = async_task("2", 1.5)
# 并发运行协程
await asyncio.gather(task1, task2)
# 运行主协程
asyncio.run(main())
print("所有协程执行完毕")
十四、其他重要知识点
1. 上下文管理器
自动管理资源(如文件、网络连接)。
python
# 自定义上下文管理器(实现__enter__和__exit__方法)
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
# 进入with块时调用
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
# 退出with块时调用
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
print("文件已关闭")
# 使用自定义上下文管理器
with FileManager("test.txt", "w") as f:
</doubaocanvas>