Python 知识点详解(三)

九、面向对象编程

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>
相关推荐
nbsaas-boot6 分钟前
Java 正则表达式白皮书:语法详解、工程实践与常用表达式库
开发语言·python·mysql
仗剑_走天涯9 分钟前
基于pytorch.nn模块实现线性模型
人工智能·pytorch·python·深度学习
chao_78910 分钟前
二分查找篇——搜索旋转排序数组【LeetCode】两次二分查找
开发语言·数据结构·python·算法·leetcode
chao_7895 小时前
二分查找篇——搜索旋转排序数组【LeetCode】一次二分查找
数据结构·python·算法·leetcode·二分查找
烛阴5 小时前
Python装饰器解除:如何让被装饰的函数重获自由?
前端·python
noravinsc6 小时前
django 一个表中包括id和parentid,如何通过parentid找到全部父爷id
python·django·sqlite
ajassi20006 小时前
开源 python 应用 开发(三)python语法介绍
linux·python·开源·自动化
沉默媛6 小时前
如何安装python以及jupyter notebook
开发语言·python·jupyter
Deng9452013147 小时前
基于Python的旅游数据可视化应用
python·numpy·pandas·旅游·数据可视化技术
2401_878624797 小时前
pytorch 自动微分
人工智能·pytorch·python·机器学习