10、面向对象编程和装饰器
一、面向对象编程
1. 什么是面向对象编程
面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它将数据(属性)和操作数据的方法(行为)封装在对象中。
2. 什么是类
在Python中,类是创建对象的蓝图。通过引用对类的属性和方法进行操作,可以创建多个对象。(如:Person类)
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
3. 什么是对象
对象是类的实例,是类的具体表现。创建一个类的具体实例对象后,可以访问类的属性和方法。(如:Person类的实例对象person)
person = Person("Alice", 30)
4. 什么是方法
方法是类中定义的函数,用于实现类的功能。方法可以访问类的属性和方法。(如:Person类中的greet方法)
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def greet(self):
        print(f"Hello, my name is {self.name} and I am {self.age} years old.")
5. 什么是属性
属性是类中定义的变量,用于存储对象的状态。属性可以被访问和修改。(如:Person类中的name和age属性)
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade
    def introduce(self):
        print(f"hi, my name is {self.name} ")
        print("my grade is:" +str(self.grade))
    def improve(self,amount):
        self.grade += amount   
QinNin=Student("QinNin",90) 
QinNin.introduce()  # 输出:hi, my name is QinNin, my grade is:90
QinNin.improve(10)
QinNin.introduce()  # 输出:hi, my name is QinNin, my grade is:100
6. 继承
继承是面向对象编程中的一个重要概念,它允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以重写父类的方法,也可以添加新的方法和属性。(如:Person类继承Student类)
class Person(Student):
    def __init__(self, name, age, grade):
        super().__init__(name, grade)
        self.age = age
    def introduce(self):
        print(f"hi, my name is {self.name} ")
        print("my grade is:" +str(self.grade))
        print("I am " +str(self.age) + " years old.")
    def improve(self,amount):
        self.grade += amount   
QinNin=Person("QinNin",90,20) 
QinNin.introduce()  # 输出:hi, my name is QinNin, my grade is:90, I am 20 years old.
QinNin.improve(10)
QinNin.introduce()  # 输出:hi, my name is QinNin, my grade is:100, I am 20 years old.
7. 多态
多态是面向对象编程中的一个重要概念,它允许一个类(子类)重写父类的方法,以实现不同的行为。多态性可以提高代码的灵活性和可扩展性。
class Teacher(Student):
    def __init__(self, name, grade, salary):
        super().__init__(name, grade)
        self.salary = salary
    def improve(self, amount):
        self.grade += amount
        self.salary += amount
    def introduce(self):
        print(f"hi, my name is {self.name} ")
        print("my grade is:" +str(self.grade))
        print("I earn " +str(self.salary) + " dollars per year.")
QinNin=Teacher("QinNin",90,50000) 
QinNin.introduce()  # 输出:hi, my name is QinNin, my grade is:90, I earn 50000 dollars per year.
QinNin.improve(10)
QinNin.introduce()  # 输出:hi, my name is QinNin, my grade is:100, I earn 50000 dollars per year.
二、装饰器
装饰器是面向对象编程中的一个重要概念,它允许在不修改类或方法的情况下,添加额外的功能。装饰器通常用于日志记录、性能监控、权限控制等场景。本质是一个高阶函数,其核心目标是 动态修改函数/类的行为,而无需直接修改原函数/类的代码。
- 开放:允许通过装饰器扩展功能 
- 封闭:禁止修改原函数/类的代码 
1. 基础装饰器
当使用 @my_decorator 时,Python 会自动执行 my_function = my_decorator(my_function),将原函数替换为装饰后的 wrapper 函数。执行 my_function() 时,实际调用的是 wrapper 函数
def my_decorator(func):  # 接收被装饰函数
    def wrapper(*args, **kwargs):  # 包装原函数
        print("装饰器逻辑:函数执行前")
        result = func(*args, **kwargs)  # 调用原函数
        print("装饰器逻辑:函数执行后")
        return result
    return wrapper  # 返回包装后的函数
@my_decorator  # 语法糖
def my_function():
    print("原函数逻辑")  
    
my_function()  # 等效于 my_function = my_decorator(my_function)
# 装饰器逻辑:函数执行前 
# 原函数逻辑 
# 装饰器逻辑:函数执行后
2.保留原函数元信息
使用 functools.wraps 避免丢失原函数的名称、文档等属性:
from functools import wraps
def my_decorator(func):
    @wraps(func)  # 保留原函数元信息
    def wrapper(*args, **kwargs):
        print("装饰器逻辑:函数执行前")
        result = func(*args, **kwargs)
        print("装饰器逻辑:函数执行后")
        return result
    return wrapper
@my_decorator
def my_function():
    print("原函数逻辑")
    
my_function()
# 装饰器逻辑:函数执行前 
# 原函数逻辑 
# 装饰器逻辑:函数执行后
3.带参数的装饰器
通过嵌套函数实现参数传递:
def repeat(n_times):  # 接收装饰器参数
    def decorator(func):  # 接收被装饰函数
        @wraps(func)
        def wrapper(*args, **kwargs):
            for _ in range(n_times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator
@repeat(n_times=3)  # 使用带参数的装饰器
def greet(name):
    print(f"Hello {name}!")
# 等效于 greet = repeat(n_times=3)(greet)
greet("QinNin")
# 输出:
# Hello QinNin!
# Hello QinNin!
# Hello QinNin!
4.类装饰器
类装饰器是面向对象编程中的一个重要概念,通过实现 __call__ 方法让类成为装饰器,它允许在不修改类或方法的情况下,添加额外的功能。类装饰器通常用于日志记录、性能监控、权限控制等场景。
class Timer:
    def __init__(self, func):
        self.func = func
    def __call__(self, *args, **kwargs):
        import time
        start = time.time()
        result = self.func(*args, **kwargs)
        end = time.time()
        print(f"{self.func.__name__} 执行耗时: {end - start:.2f}s")
        return result
@Timer
def long_running_func():
    time.sleep(2)
# 调用时自动计时
long_running_func()
# 输出:
# long_running_func 执行耗时: 2.00s
5.元类
元类是面向对象编程中的一个重要概念,它允许在不修改类或方法的情况下,添加额外的功能。元类通常用于日志记录、性能监控、权限控制等场景。
class Meta(type):
    def __init__(cls, name, bases, attrs):
        print("元类逻辑:类定义时执行")
        super().__init__(name, bases, attrs)
class MyClass(metaclass=Meta):
    pass
# 输出:
# 元类逻辑:类定义时执行
