Python类——进阶 1. 抽象类的定义与实现 什么是抽象类? 抽象类是一种不能被实例化的类,它的主要作用是定义接口和规范,强制子类实现特定的方法。在Python中,抽象类通过abc模块(Abstract Base Classes)来实现。
使用abc模块创建抽象基类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from abc import ABC, abstractmethodclass Animal (ABC ): """动物抽象基类""" @abstractmethod def eat (self ): """吃方法""" pass @abstractmethod def sleep (self ): """睡觉方法""" pass def breathe (self ): """呼吸方法(非抽象方法,有默认实现)""" print ("Breathing..." )
抽象类的继承规则
子类必须实现所有抽象方法,否则子类也会成为抽象类
子类可以重写非抽象方法
抽象类可以包含非抽象方法(带有默认实现)
实际应用场景
定义接口规范,确保所有子类都实现特定方法
提供通用的方法实现,减少代码重复
实现多态,通过抽象基类统一处理不同的实现
完整实现示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 from abc import ABC, abstractmethodclass Shape (ABC ): """形状抽象基类""" @abstractmethod def area (self ): """计算面积""" pass @abstractmethod def perimeter (self ): """计算周长""" pass class Circle (Shape ): """圆形类""" def __init__ (self, radius ): self .radius = radius def area (self ): return 3.14159 * self .radius ** 2 def perimeter (self ): return 2 * 3.14159 * self .radius class Rectangle (Shape ): """矩形类""" def __init__ (self, width, height ): self .width = width self .height = height def area (self ): return self .width * self .height def perimeter (self ): return 2 * (self .width + self .height) circle = Circle(5 ) print (f"Circle area: {circle.area()} " )print (f"Circle perimeter: {circle.perimeter()} " )rectangle = Rectangle(4 , 6 ) print (f"Rectangle area: {rectangle.area()} " )print (f"Rectangle perimeter: {rectangle.perimeter()} " )
2. 私有方法与属性 命名规范 Python中没有真正的私有成员,而是通过命名约定来实现:
单下划线前缀 (如_private):表示保护成员,建议外部不要直接访问
双下划线前缀 (如__private):表示私有成员,会触发名称修饰(name mangling)
名称修饰机制 当使用双下划线前缀时,Python会自动将名称修改为_ClassName__private的形式,这样可以避免子类中的命名冲突。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class MyClass : def __init__ (self ): self ._protected = "protected" self .__private = "private" def _protected_method (self ): return "This is a protected method" def __private_method (self ): return "This is a private method" obj = MyClass() print (obj._protected) print (obj._MyClass__private) print (obj._protected_method()) print (obj._MyClass__private_method())
私有成员的间接访问 可以通过公共方法来间接访问私有成员:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Person : def __init__ (self, name, age ): self .name = name self .__age = age def get_age (self ): return self .__age def set_age (self, age ): if age > 0 : self .__age = age else : raise ValueError("Age must be positive" ) person = Person("Alice" , 30 ) print (person.get_age()) person.set_age(31 ) print (person.get_age()) print (person.get_age())
3. 类相关常用注解 @classmethod 作用 :定义类方法,第一个参数是类本身(通常命名为cls)
使用场景 :
当方法需要访问或修改类级别的属性时
作为工厂方法创建类的实例
提供与类相关的工具方法
语法格式 :
1 2 3 4 class MyClass : @classmethod def class_method (cls, param1, param2 ):
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Date : def __init__ (self, year, month, day ): self .year = year self .month = month self .day = day @classmethod def from_string (cls, date_string ): """从字符串创建日期对象""" year, month, day = map (int , date_string.split('-' )) return cls(year, month, day) @classmethod def today (cls ): """获取今天的日期""" import datetime today = datetime.date.today() return cls(today.year, today.month, today.day) date1 = Date(2023 , 12 , 25 ) date2 = Date.from_string("2023-12-25" ) date3 = Date.today()
@staticmethod 作用 :定义静态方法,不接收特殊的第一个参数(既不是self也不是cls)
使用场景 :
当方法不需要访问实例或类的属性时
提供与类相关但独立于实例的功能
作为工具方法
语法格式 :
1 2 3 4 class MyClass : @staticmethod def static_method (param1, param2 ):
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 class MathUtils : @staticmethod def add (a, b ): return a + b @staticmethod def multiply (a, b ): return a * b result1 = MathUtils.add(5 , 3 ) result2 = MathUtils.multiply(5 , 3 )
@property 作用 :将方法转换为属性,使得可以像访问属性一样调用方法
使用场景 :
实现属性的getter方法
对属性访问进行控制和验证
计算属性值
语法格式 :
1 2 3 4 5 6 7 8 class MyClass : @property def property_name (self ): @property_name.setter def property_name (self, value ):
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Person : def __init__ (self, name, age ): self .name = name self ._age = age @property def age (self ): return self ._age @age.setter def age (self, value ): if value > 0 : self ._age = value else : raise ValueError("Age must be positive" ) person = Person("Bob" , 25 ) print (person.age) person.age = 26 print (person.age)
@abstractmethod 作用 :定义抽象方法,强制子类实现
使用场景 :
在抽象基类中定义必须由子类实现的方法
确保所有子类都遵循相同的接口
语法格式 :
1 2 3 4 5 6 from abc import ABC, abstractmethodclass MyAbstractClass (ABC ): @abstractmethod def abstract_method (self ): pass
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from abc import ABC, abstractmethodclass Vehicle (ABC ): @abstractmethod def start (self ): pass @abstractmethod def stop (self ): pass class Car (Vehicle ): def start (self ): print ("Car starting..." ) def stop (self ): print ("Car stopping..." ) class Bike (Vehicle ): def start (self ): print ("Bike starting..." ) def stop (self ): print ("Bike stopping..." )
4. 项目工程中的类定义规范 命名规范
类名 :使用大驼峰命名法(PascalCase),如MyClass
方法名 :使用小驼峰命名法(camelCase),如myMethod
属性名 :使用小驼峰命名法,如myProperty
私有成员 :使用单下划线或双下划线前缀,如_private或__private
常量 :使用全大写字母和下划线,如MAX_VALUE
代码组织结构
每个模块(.py文件)应该包含相关的类和函数
类应该按照逻辑关系组织,相关的类放在同一个模块中
大型项目应该使用包(package)来组织模块
合理使用继承和组合,避免过度继承
文档字符串格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class MyClass : """类的文档字符串 详细描述类的功能、用途和使用方法 Attributes: attribute1 (type): 描述 attribute2 (type): 描述 """ def my_method (self, param1, param2 ): """方法的文档字符串 详细描述方法的功能、参数和返回值 Args: param1 (type): 参数描述 param2 (type): 参数描述 Returns: type: 返回值描述 Raises: ExceptionType: 异常描述 """
类继承关系设计原则
单一职责原则 :一个类应该只负责一项功能
开闭原则 :对扩展开放,对修改关闭
里氏替换原则 :子类应该能够替换父类
接口隔离原则 :使用多个专门的接口而不是一个宽泛的接口
依赖倒置原则 :依赖于抽象,而不是具体实现
实际项目示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Validator : """验证器基类""" def validate (self, value ): """验证值""" pass class EmailValidator (Validator ): """邮箱验证器""" def validate (self, value ): pass class User : """用户类""" def __init__ (self, name, email ): self .name = name self .email = email def validate (self ): """验证用户数据""" validator = EmailValidator() return validator.validate(self .email)
5. Python类之间的设计模式 单例模式 适用场景 :当只需要一个类的实例时,如配置管理、数据库连接池等
实现方式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Singleton : _instance = None def __new__ (cls, *args, **kwargs ): if not cls._instance: cls._instance = super ().__new__(cls) return cls._instance class Database (Singleton ): def __init__ (self, connection_string ): if not hasattr (self , 'initialized' ): self .connection_string = connection_string self .initialized = True db1 = Database("localhost:5432" ) db2 = Database("localhost:5432" ) print (db1 is db2)
工厂模式 适用场景 :当需要根据不同条件创建不同类型的对象时
实现方式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from abc import ABC, abstractmethodclass Product (ABC ): @abstractmethod def operation (self ): pass class ConcreteProductA (Product ): def operation (self ): return "Product A operation" class ConcreteProductB (Product ): def operation (self ): return "Product B operation" class Factory : def create_product (self, product_type ): if product_type == "A" : return ConcreteProductA() elif product_type == "B" : return ConcreteProductB() else : raise ValueError(f"Unknown product type: {product_type} " ) factory = Factory() product_a = factory.create_product("A" ) product_b = factory.create_product("B" ) print (product_a.operation()) print (product_b.operation())
观察者模式 适用场景 :当一个对象的状态变化需要通知其他对象时
实现方式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Subject : def __init__ (self ): self .observers = [] def attach (self, observer ): if observer not in self .observers: self .observers.append(observer) def detach (self, observer ): if observer in self .observers: self .observers.remove(observer) def notify (self ): for observer in self .observers: observer.update(self ) class Observer : def update (self, subject ): pass class ConcreteObserverA (Observer ): def update (self, subject ): print (f"Observer A received update from {subject} " ) class ConcreteObserverB (Observer ): def update (self, subject ): print (f"Observer B received update from {subject} " ) subject = Subject() observer_a = ConcreteObserverA() observer_b = ConcreteObserverB() subject.attach(observer_a) subject.attach(observer_b) subject.notify() subject.detach(observer_a) subject.notify()
装饰器模式 适用场景 :当需要动态地为对象添加额外的功能时
实现方式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from abc import ABC, abstractmethodclass Component (ABC ): @abstractmethod def operation (self ): pass class ConcreteComponent (Component ): def operation (self ): return "ConcreteComponent operation" class Decorator (Component ): def __init__ (self, component ): self .component = component def operation (self ): return self .component.operation() class ConcreteDecoratorA (Decorator ): def operation (self ): return f"ConcreteDecoratorA({self.component.operation()} )" class ConcreteDecoratorB (Decorator ): def operation (self ): return f"ConcreteDecoratorB({self.component.operation()} )" component = ConcreteComponent() decorator_a = ConcreteDecoratorA(component) decorator_b = ConcreteDecoratorB(decorator_a) print (decorator_b.operation())
总结 Python类的进阶特性为我们提供了强大的面向对象编程能力,包括:
抽象类 :通过abc模块实现,强制子类实现特定方法,定义接口规范
私有成员 :通过命名约定实现,保护类的内部状态
类注解 :如@classmethod、@staticmethod、@property等,提供了更灵活的方法定义方式
工程规范 :良好的命名、组织和文档规范,提高代码质量和可维护性
设计模式 :如单例模式、工厂模式、观察者模式等,解决常见的设计问题
掌握这些进阶特性,可以帮助我们编写更加优雅、高效、可维护的Python代码。在实际项目开发中,应该根据具体需求选择合适的特性和设计模式,遵循最佳实践,构建高质量的软件系统。