本文目录导读:

我来详细解释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代码至关重要。