Skip to main content

Python 面向对象

Python 实例属性和类属性

Python实例属性:属于类的具体实例,每个实例拥有自己独立的数据,存储在实例对象中。通常在 __init__ 方法中使用 self 定义。类属性:属于类本身,所有实例共享同一份数据,存储在类对象中。通常在类定义的顶层(方法外部)定义。理解两者的区别是掌握OOP的重要一步。

定义和访问实例属性

实例属性通过 self__init__ 方法或其他实例方法中定义,每个实例的属性值互不影响。

以下是一个实例属性的示例:

class Student:
    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age    # 实例属性

    def introduce(self):
        print(f"我是 {self.name},{self.age} 岁")

student1 = Student("Alice", 20)
student2 = Student("Bob", 22)
print(student1.name, student1.age)  # 输出: Alice 20
print(student2.name, student2.age)  # 输出: Bob 22
student1.introduce()                # 输出: 我是 Alice,20 岁

在这个例子中:

  • nameage 是实例属性,每个 Student 实例(如 student1student2)有自己的值。
  • 实例属性通过 self 访问,互不干扰。

定义和访问类属性

类属性在类定义中直接声明,所有实例共享同一份数据。修改类属性会影响所有实例,除非实例创建了自己的同名属性。

以下是类属性的示例:

class Student:
    school = "阳光中学"    # 类属性

    def __init__(self, name):
        self.name = name  # 实例属性

    def show_school(self):
        print(f"{self.name} 的学校是 {Student.school}")

student1 = Student("Alice")
student2 = Student("Bob")
print(Student.school)      # 输出: 阳光中学
print(student1.school)     # 输出: 阳光中学
print(student2.school)     # 输出: 阳光中学
student1.show_school()     # 输出: Alice 的学校是 阳光中学

在这个例子中:

  • school 是类属性,存储在 Student 类中,所有实例共享。
  • 类属性可以通过类名(Student.school)或实例(student1.school)访问。

修改类属性与实例属性的区别

  • 修改类属性:通过类名修改会影响所有实例。
  • 修改实例属性:只影响特定实例。
  • 如果通过实例修改类属性,会为该实例创建一个同名的实例属性,屏蔽类属性。

以下是修改属性的示例:

class Student:
    school = "阳光中学"    # 类属性

    def __init__(self, name):
        self.name = name  # 实例属性

student1 = Student("Alice")
student2 = Student("Bob")
Student.school = "希望中学"     # 修改类属性
print(student1.school)        # 输出: 希望中学
print(student2.school)        # 输出: 希望中学

student1.school = "星光中学"    # 为 student1 创建实例属性
print(student1.school)        # 输出: 星光中学
print(student2.school)        # 输出: 希望中学
print(Student.school)         # 输出: 希望中学

在这个例子中:

  • 通过 Student.school 修改类属性,影响所有实例。
  • student1.school = "星光中学"student1 创建一个实例属性 school,不影响类属性或其他实例。

类属性与继承

类属性在继承中会被子类继承,子类可以直接访问或修改父类的类属性。

以下是继承中类属性的示例:

class Person:
    species = "人类"        # 类属性

    def __init__(self, name):
        self.name = name

class Student(Person):
    def show_info(self):
        print(f"{self.name} 属于 {Student.species}")

student = Student("Alice")
print(student.species)     # 输出: 人类
student.show_info()        # 输出: Alice 属于 人类
Student.species = "学生"    # 修改子类的类属性
print(student.species)     # 输出: 学生
print(Person.species)      # 输出: 人类

在这个例子中:

  • Student 继承了 Person 的类属性 species
  • 修改 Student.species 不会影响 Person.species

使用场景与注意事项

  • 实例属性:适合存储与特定实例相关的数据,如姓名、年龄。
  • 类属性:适合存储所有实例共享的常量或状态,如配置信息、计数器。
  • 注意事项
    • 避免通过实例修改类属性,以免意外创建同名实例属性。
    • 类属性适合定义全局默认值,但需注意其共享性。
    • 在继承中,子类修改类属性不会影响父类。

总结

实例属性和类属性是Python OOP中管理数据的两种方式:

  • 实例属性:每个实例独立,定义在 __init__ 中,使用 self
  • 类属性:所有实例共享,定义在类顶层,通过类名或实例访问。
  • 理解两者的作用域和修改规则有助于编写清晰、可维护的代码。