【Python高级】05_其他特性(类属性等)

0 阅读5分钟

🚗 Python 类属性、类方法与静态方法详解

这份笔记深入解析了 Python 面向对象编程中三个核心概念:类属性类方法静态方法,并结合了具体的代码示例和实战练习。

🧠 知识点思维导图

image.png


1. 类属性

类属性是属于类本身的数据,而不是属于某个具体对象的。它在所有实例之间共享同一份数据

核心要点

  • 定义位置:类体内,方法之外。

  • 共享性:所有实例共享同一个类属性。

  • 修改规则

    • 正确方式:使用 类名.属性 = 值 修改,会影响所有实例。
    • 错误/陷阱方式:使用 实例.属性 = 值 修改,不会修改类属性,而是给该实例创建了一个同名的实例属性,仅影响当前实例。

代码示例

class Car(object):
    """
    定义一个汽车类
    """
    wheel = 4  # 类属性:所有汽车默认4个轮子
    count = 0  # 类属性:统计创建的汽车数量

    def __init__(self, brand, color):
        self.brand = brand       # 实例属性
        self.color = color       # 实例属性
        Car.count += 1           # 创建一辆车,类属性计数加1

    def run(self):
        print(f"{self.brand}汽车开始行驶")

    def __str__(self):
        return f"{self.brand}汽车颜色是{self.color},轮子数量是{self.wheel}"

# --- 测试代码 ---
c1 = Car("保时捷", "黑色")
print("1:", c1.count)  # 输出: 1

# ⚠️ 陷阱:使用 对象.类属性 修改
c1.wheel = 6 
# 解释:这行代码并没有修改 Car 类的 wheel 属性,而是给 c1 对象新增了一个实例属性 wheel
print("2:", c1.wheel)  # 输出: 6 (访问的是 c1 的实例属性)

# ✅ 正确:使用 类名.类属性 修改
Car.wheel = 8 
# 解释:这行代码修改了类属性,会影响所有未屏蔽该属性的实例

c2 = Car("法拉利", "蓝色")
print("3:", c2.count)  # 输出: 2
print("4:", c2.wheel)  # 输出: 8 (c2 没有实例属性 wheel,访问的是类属性)
print(c2)              # 输出: 法拉利汽车颜色是蓝色,轮子数量是8

小结:一般情况下,建议使用类方法来操作类属性,而不是直接通过类属性操作,这样更安全且易于维护。

image.png

运行结果:

image.png


2. 类方法

类方法是操作类属性的最佳方式。

核心要点

  • 装饰器@classmethod
  • 第一个参数cls(约定俗成),代表类本身(例如 Car),而不是实例。
  • 能力:可以访问和修改类属性(cls.wheel),也可以创建实例。

代码示例

class Car(object):
    """
    定义一个汽车类
    """
    wheel = 4
    count = 0

    def __init__(self, brand, color):
        self.brand = brand
        self.color = color
        Car.count += 1

    @classmethod
    def get_count(cls):
        print(f"创建的汽车数量是:{cls.count}")

    @classmethod
    def set_wheel(cls, wheel):
        cls.wheel = wheel
        print(f"设置轮子数量为:{cls.wheel}")

    @classmethod
    def set_count(cls):
        cls.count = 0
        print("把汽车数量设置为0,重新计数")

    def __str__(self):
        return f"{self.brand}汽车颜色是{self.color},轮子数量是{self.wheel}"

# --- 测试代码 ---
car = Car("保时捷", "蓝色")
Car.get_count()       # 输出: 创建的汽车数量是:1

car2 = Car("法拉利", "蓝色")
Car.get_count()       # 输出: 创建的汽车数量是:2

Car.set_wheel(6)      # 通过类方法修改类属性
print(car)            # 输出: 保时捷汽车颜色是蓝色,轮子数量是6 (类属性改变,影响所有实例)

image.png

运行结果:

image.png


3. 静态方法

静态方法通常作为工具方法使用,与类或实例的状态无关。

核心要点

  • 装饰器@staticmethod
  • 参数:不需要 self 或 cls 参数。
  • 能力不能直接访问类属性或实例属性(除非手动通过类名访问)。
  • 用途:逻辑上属于该类的工具函数(如数据校验、数学计算)。

代码示例

class StudentManage(object):
    """
    定义一个学生管理类
    """
    @staticmethod
    def menu():
        print("1.学生登录")
        print("2.学生管理")
        print("3.退出系统")

    @staticmethod
    def sum_students(class_count, student_number):
        return class_count * student_number

# --- 测试代码 ---
StudentManage.menu()
print(StudentManage.sum_students(5, 20)) # 输出: 100

4. 类方法与静态方法的对比

表格

特性类方法 (@classmethod)静态方法 (@staticmethod)
第一个参数cls (类本身)无强制参数
访问类属性✅ 可以访问和修改 (cls.attr)❌ 不能直接访问 (需通过类名)
访问实例属性❌ 不能访问❌ 不能访问
主要用途修改类状态、工厂模式工具函数、逻辑分组
继承特性支持多态 (调用时 cls 指向子类)不具备多态性,行为像普通函数

image.png

image.png

运行结果:

image.png

5. 综合实战练习:支付系统

需求:实现一个支付类。

  1. 实例方法:实现支付功能(扣除余额)。
  2. 类方法:实现设置支付费率(修改全局费率)。
  3. 静态方法:实现校验支付金额(工具函数)。
class Payment(object):
    pay_rate = 0.05        # 类属性:默认费率 5%
    account_balance = 10000 # 类属性:默认账户余额

    def __init__(self, balance=0):
        # 如果传入了余额,则更新实例的余额(注意:这里实际上创建了实例属性,遮蔽了类属性)
        if balance > 0:
            self.account_balance = balance

    # --- 实例方法 ---
    def pay(self, amount):
        if amount:
            # 计算含手续费的金额
            total_cost = amount * (1 + self.pay_rate)
            print(f"支付了 {total_cost}元")
            self.account_balance -= total_cost
        else:
            print("请输入正确的支付金额")

    # --- 类方法 ---
    @classmethod
    def set_pay_rate(cls, pay_rate):
        cls.pay_rate = pay_rate

    # --- 静态方法 ---
    @staticmethod
    def check_amount(amount):
        if 0 < amount <= 5000:
            return amount
        else:
            print("金额超出范围")
            return 0

    def __str__(self):
        return f"账户余额:{self.account_balance}"

# --- 测试流程 ---
payment = Payment()

# 1. 使用静态方法校验金额
amount = Payment.check_amount(1000) # 返回 1000

# 2. 使用实例方法支付 (使用默认费率 0.05)
payment.pay(amount) 
# 输出: 支付了 1050.0元

print(payment.pay_rate) # 输出: 0.05

# 3. 使用类方法修改费率
Payment.set_pay_rate(0.08) # 全局费率变为 8%

print(payment.pay_rate) # 输出: 0.08 (实例访问到了更新后的类属性)

# 4. 再次支付 (使用新费率)
payment.pay(amount)
# 输出: 支付了 1080.0元

print(amount)

image.png

运行结果:

image.png