Python案例怎么使用类属性?

wen python案例 13

本文目录导读:

Python案例怎么使用类属性?

  1. 什么是类属性
  2. 类属性的访问方式
  3. 类属性的修改
  4. 实用案例
  5. 类属性 vs 实例属性
  6. 注意事项

我来详细解释Python中类属性的使用方法,通过具体案例说明。

什么是类属性

类属性是属于类本身的属性,所有实例共享同一个类属性。

class Student:
    # 类属性
    school = "清华中学"
    student_count = 0
    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age    # 实例属性
        Student.student_count += 1  # 每创建一个实例,计数加1
# 使用类属性
print(Student.school)  # 输出:清华中学
print(Student.student_count)  # 输出:0
s1 = Student("小明", 15)
s2 = Student("小红", 16)
print(Student.student_count)  # 输出:2

类属性的访问方式

通过类名访问

class Car:
    wheels = 4
    manufacturer = "中国"
print(Car.wheels)  # 4
print(Car.manufacturer)  # 中国

通过实例访问

car1 = Car()
car2 = Car()
print(car1.wheels)  # 4
print(car2.wheels)  # 4
print(car1.manufacturer)  # 中国

类属性的修改

通过类名修改(影响所有实例)

class Employee:
    company = "科技公司"
    raise_amount = 1.05
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
    def apply_raise(self):
        self.salary = int(self.salary * Employee.raise_amount)
emp1 = Employee("张三", 50000)
emp2 = Employee("李四", 60000)
# 修改类属性
Employee.raise_amount = 1.10
Employee.company = "新科技公司"
print(emp1.raise_amount)  # 1.10
print(emp2.raise_amount)  # 1.10
print(emp1.company)  # 新科技公司

通过实例修改(只影响该实例)

class Dog:
    species = "金毛"
    legs = 4
dog1 = Dog()
dog2 = Dog()
dog1.legs = 3  # 只修改dog1的legs属性(创建实例属性)
print(dog1.legs)  # 3
print(dog2.legs)  # 4(仍然使用类属性)
print(Dog.legs)   # 4(类属性未变)

实用案例

案例1:银行账户管理系统

class BankAccount:
    # 类属性
    bank_name = "中国银行"
    interest_rate = 0.03
    account_counter = 1000  # 账户编号计数器
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance
        self.account_number = BankAccount.generate_account_number()
    @classmethod
    def generate_account_number(cls):
        cls.account_counter += 1
        return f"BANK{cls.account_counter}"
    @classmethod
    def set_interest_rate(cls, new_rate):
        cls.interest_rate = new_rate
    def calculate_interest(self):
        return self.balance * BankAccount.interest_rate
    def __str__(self):
        return f"{self.owner}的账户({self.account_number})- 余额:{self.balance}"
# 使用
account1 = BankAccount("张三", 10000)
account2 = BankAccount("李四", 20000)
print(f"银行名称:{BankAccount.bank_name}")
print(f"当前利率:{BankAccount.interest_rate}")
# 修改利率
BankAccount.set_interest_rate(0.035)
print(f"新利率:{BankAccount.interest_rate}")
print(account1)
print(f"{account1.owner}的利息:{account1.calculate_interest()}")
print(account2)
print(f"{account2.owner}的利息:{account2.calculate_interest()}")

案例2:配置管理

class DatabaseConfig:
    # 类属性作为配置
    host = "localhost"
    port = 3306
    database = "mydb"
    username = "admin"
    password = "password123"
    max_connections = 100
    @classmethod
    def get_config(cls):
        return {
            "host": cls.host,
            "port": cls.port,
            "database": cls.database,
            "user": cls.username,
            "password": cls.password,
            "max_connections": cls.max_connections
        }
    @classmethod
    def update_config(cls, **kwargs):
        for key, value in kwargs.items():
            if hasattr(cls, key):
                setattr(cls, key, value)
class ProductionConfig(DatabaseConfig):
    host = "prod-server.com"
    database = "production_db"
    max_connections = 500
class DevelopmentConfig(DatabaseConfig):
    host = "localhost"
    database = "dev_db"
    debug = True
# 使用
print("开发环境配置:")
print(DevelopmentConfig.get_config())
print("\n生产环境配置:")
print(ProductionConfig.get_config())
# 动态修改配置
DatabaseConfig.update_config(port=3307, max_connections=200)
print("\n修改后的配置:")
print(DatabaseConfig.get_config())

案例3:统计和跟踪

class StudentManager:
    # 类属性用于统计
    total_students = 0
    total_grades = 0
    all_students = []  # 存储所有学生实例
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade
        StudentManager.total_students += 1
        StudentManager.total_grades += grade
        StudentManager.all_students.append(self)
    @classmethod
    def get_average_grade(cls):
        if cls.total_students == 0:
            return 0
        return cls.total_grades / cls.total_students
    @classmethod
    def get_top_student(cls):
        if not cls.all_students:
            return None
        return max(cls.all_students, key=lambda s: s.grade)
    @classmethod
    def print_statistics(cls):
        print(f"学生总数:{cls.total_students}")
        print(f"平均成绩:{cls.get_average_grade():.2f}")
        if cls.all_students:
            top = cls.get_top_student()
            print(f"最高分学生:{top.name}({top.grade}分)")
# 使用
students = [
    StudentManager("小明", 92),
    StudentManager("小红", 88),
    StudentManager("小华", 95),
    StudentManager("小丽", 78)
]
StudentManager.print_statistics()
# 输出:
# 学生总数:4
# 平均成绩:88.25
# 最高分学生:小华(95分)

类属性 vs 实例属性

class Example:
    class_attr = "类属性"
    def __init__(self, instance_value):
        self.instance_attr = instance_value
    def demonstrate(self):
        print(f"类属性:{Example.class_attr}")
        print(f"实例属性:{self.instance_attr}")
# 比较
e1 = Example("实例1的值")
e2 = Example("实例2的值")
print("=== 访问方式 ===")
print(f"通过类名访问类属性:{Example.class_attr}")
print(f"通过实例访问类属性:{e1.class_attr}")
print(f"通过实例访问实例属性:{e1.instance_attr}")
print("\n=== 修改影响 ===")
Example.class_attr = "修改后的类属性"
print(f"e1的类属性:{e1.class_attr}")  # 修改后的类属性
print(f"e2的类属性:{e2.class_attr}")  # 修改后的类属性
e1.instance_attr = "只修改e1"
print(f"e1的实例属性:{e1.instance_attr}")  # 只修改e1
print(f"e2的实例属性:{e2.instance_attr}")  # 实例2的值

注意事项

警惕可变对象的类属性

class ProblemExample:
    shared_list = []  # 注意:所有实例共享同一个列表
    shared_dict = {}  # 注意:所有实例共享同一个字典
    def add_to_list(self, item):
        self.shared_list.append(item)
    def add_to_dict(self, key, value):
        self.shared_dict[key] = value
p1 = ProblemExample()
p2 = ProblemExample()
p1.add_to_list("p1添加")
p1.add_to_dict("key1", "value1")
print(p2.shared_list)  # ['p1添加']  - p2也看到了p1添加的值
print(p2.shared_dict)  # {'key1': 'value1'}  - 同样的问题
# 正确做法:在__init__中创建新实例
class GoodExample:
    def __init__(self):
        self.my_list = []  # 每个实例有自己独立的列表
        self.my_dict = {}

类属性适合存储所有实例共享的数据,如配置、常量、计数器等,理解类属性和实例属性的区别对于编写正确的Python代码至关重要。

抱歉,评论功能暂时关闭!