从零开始学Python系列-第17讲:面向对象编程进阶

从零开始学Python系列-第17讲:面向对象编程进阶
最新回答
心痛亦已

2026-10-21 22:01:20

Python面向对象编程进阶

在上一讲中,我们介绍了Python面向对象编程的基础知识,包括类的定义、对象的创建以及基本的方法调用。这一讲,我们将深入探讨Python面向对象编程的进阶内容,包括可见性与属性装饰器、动态属性、静态方法与类方法,以及继承与多态。

可见性与属性装饰器

在面向对象编程中,对象的属性通常会被设置为私有(private)或受保护(protected)的成员,以限制外部直接访问。在Python中,可以通过给对象属性名添加前缀下划线的方式来说明属性的访问可见性:

  • 私有属性:以双下划线__开头的属性,如__name,表示私有属性,外部无法直接访问。
  • 受保护属性:以单下划线_开头的属性,如_name,表示受保护属性,虽然可以直接访问,但按照约定应视为内部使用。
class Student: def __init__(self, name, age): self.__name = name # 私有属性 self._age = age # 受保护属性 def study(self, course_name): print(f'{self.__name}正在学习{course_name}.')stu = Student('王大锤', 20)stu.study('Python程序设计')# print(stu.__name) # 会引发AttributeErrorprint(stu._age) # 可以访问,但不推荐

Python并没有严格限制私有属性的访问,只是通过名称修饰(name mangling)来阻挠直接访问。例如,__name实际上会被修改为_Student__name,因此可以通过这种方式间接访问:

print(stu._Student__name) # 输出:王大锤

为了更优雅地控制属性的访问,Python提供了property装饰器,允许我们为私有属性定义getter和setter方法:

class Student: def __init__(self, name, age): self.__name = name self.__age = age @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name or '无名氏' @property def age(self): return self.__agestu = Student('王大锤', 20)print(stu.name) # 输出:王大锤stu.name = ''print(stu.name) # 输出:无名氏动态属性

Python是一门动态语言,允许在运行时动态地为对象添加属性。这是Python灵活性的体现:

class Student: def __init__(self, name, age): self.name = name self.age = agestu = Student('王大锤', 20)stu.sex = '男' # 动态添加属性print(stu.sex) # 输出:男

如果不希望对象动态添加属性,可以使用__slots__来限制:

class Student: __slots__ = ('name', 'age') # 限制只能有name和age属性 def __init__(self, name, age): self.name = name self.age = agestu = Student('王大锤', 20)# stu.sex = '男' # 会引发AttributeError静态方法与类方法

在面向对象编程中,除了对象方法外,还可以定义静态方法和类方法。这两类方法是发送给类的消息,而不是发送给对象的消息。

  • 静态方法:使用@staticmethod装饰器定义,不接收任何隐含的第一个参数(如self或cls)。
  • 类方法:使用@classmethod装饰器定义,接收类对象cls作为第一个参数。
class Triangle: def __init__(self, a, b, c): self.a = a self.b = b self.c = c @staticmethod def is_valid(a, b, c): return a + b > c and b + c > a and a + c > b @classmethod def from_list(cls, sides): return cls(*sides) def perimeter(self): return self.a + self.b + self.c# 使用静态方法print(Triangle.is_valid(3, 4, 5)) # 输出:True# 使用类方法tri = Triangle.from_list([3, 4, 5])print(tri.perimeter()) # 输出:12继承与多态

继承是面向对象编程的重要特性,允许我们基于已有类创建新类,减少重复代码。提供继承信息的类称为父类(基类),得到继承信息的类称为子类(派生类)。

class Person: def __init__(self, name, age): self.name = name self.age = age def eat(self): print(f'{self.name}正在吃饭.')class Student(Person): def __init__(self, name, age): super().__init__(name, age) def study(self, course_name): print(f'{self.name}正在学习{course_name}.')class Teacher(Person): def __init__(self, name, age, title): super().__init__(name, age) self.title = title def teach(self, course_name): print(f'{self.name}{self.title}正在讲授{course_name}.')stu = Student('白元芳', 21)teacher = Teacher('武则天', 35, '副教授')stu.eat() # 输出:白元芳正在吃饭.teacher.teach('Python程序设计') # 输出:武则天副教授正在讲授Python程序设计.stu.study('Python程序设计') # 输出:白元芳正在学习Python程序设计.

多态是指子类可以重写父类的方法,使得不同的子类对象对同一消息可以做出不同的响应。这是面向对象编程中最精髓的部分之一。

class Animal: def speak(self): raise NotImplementedError("子类必须实现此方法")class Dog(Animal): def speak(self): print("汪汪汪!")class Cat(Animal): def speak(self): print("喵喵喵!")def animal_speak(animal): animal.speak()dog = Dog()cat = Cat()animal_speak(dog) # 输出:汪汪汪!animal_speak(cat) # 输出:喵喵喵!

在这个例子中,Dog和Cat类都继承了Animal类,并重写了speak方法。当调用animal_speak函数时,根据传入的对象类型不同,会调用相应的speak方法,这就是多态的体现。

总结

本讲我们深入探讨了Python面向对象编程的进阶内容,包括可见性与属性装饰器、动态属性、静态方法与类方法,以及继承与多态。这些概念是Python面向对象编程的重要组成部分,掌握它们对于编写高效、可维护的Python代码至关重要。