Python 面向对象进阶:构造函数、析构函数、属性、访问权限、单例模式详解 📅 2026/8/11 3:24:30 我们学习了类、继承、多继承、抽象类等面向对象知识点。在实际开发中我们经常需要控制对象初始化、对象销毁逻辑、管控成员变量访问、保证类只创建一个实例。1. 构造函数init__init__()就是 Python 的构造函数在创建对象的时候自动调用用来完成对象属性的初始化赋值。注意__init__不是真正创建对象的方法真正创建对象的是__new____init__只负责初始化class Person: # 构造函数实例化对象自动执行 def __init__(self, name, age): self.name name # 实例属性 self.age age def show_info(self): print(f姓名{self.name}年龄{self.age}) # 创建对象自动调用__init__ p Person(张三, 20) p.show_info()对象创建Person(张三,20)→ 先__new__开辟内存 → 调用__init__给对象赋值self代表当前实例对象本身必须作为第一个参数。2. 析构函数del_del__()称为析构函数当对象被垃圾回收销毁的时候自动执行一般用来做资源释放关闭文件、断开网络连接等。注意无法确定__del__确切什么时候执行Python 由 GC 垃圾回收机制控制不要过度依赖它做业务逻辑。class Person: def __init__(self,name): self.name name print(f【构造】创建对象 {self.name}) def __del__(self): # 对象销毁时自动调用 print(f【析构】对象被销毁 {self.name}) p1 Person(李四) print(程序即将结束) # 手动删除对象触发垃圾回收 del p1 print(程序运行完毕)3. 属性 property直接暴露实例属性外部可以随意修改无法做数据校验。property可以把方法伪装成属性实现外部像访问属性一样内部执行方法逻辑增加校验、拦截。3.1 基础 property 装饰器用法class Student: def __init__(self, age): self._age age # 获取属性 property def age(self): return self._age # 设置属性 age.setter def age(self, value): if not isinstance(value, int): raise ValueError(年龄必须是整数) if 0 value 150: self._age value else: raise ValueError(年龄范围必须0~150) # 删除属性 age.deleter def age(self): del self._age s Student(18) print(s.age) # 调用property不需要加括号 s.age 22 # 调用 age.setter print(s.age) # s.age 200 # 会抛出异常完成数据校验property读xxx.setter写xxx.deleter删除好处对外接口不变后期可以追加校验逻辑不需要修改外部调用代码。4. 数据访问级别公有、保护、私有Python 没有真正的访问控制关键字没有 public/private依靠命名约定实现访问级别。命名级别说明name公有内外都可以直接访问_name保护约定仅类内部、子类访问外部不要访问语法上仍可访问__name私有名字改写机制外部无法直接访问只能类内部使用class Demo: def __init__(self): self.public_val 公有变量 self._protect_val 保护变量 self.__private_val 私有变量 def show(self): # 类内部全部都可以访问 print(self.public_val) print(self._protect_val) print(self.__private_val) d Demo() print(d.public_val) print(d._protect_val) # print(d.__private_val) # 报错外部不能直接访问私有属性 # 底层名字改写不推荐使用 print(d._Demo__private_val)5. 单例类单例模式保证整个程序运行期间一个类只能创建出唯一的一个对象。应用场景配置管理器、日志对象、数据库连接对象避免重复创建多个实例浪费资源。方式 1重写new最常用__new__负责创建对象内存控制只返回同一个实例。class Singleton: # 保存唯一实例 _instance None def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance super().__new__(cls) return cls._instance def __init__(self): # 注意多次实例化 __init__依然会重复执行需要做初始化防重复 pass s1 Singleton() s2 Singleton() print(s1 is s2) # True两个变量指向同一个对象 print(id(s1), id(s2))避免__init__重复执行的单例class Singleton: _instance None _init_flag False def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance super().__new__(cls) return cls._instance def __init__(self,name): if not self._init_flag: self.name name self._init_flag True s1 Singleton(测试单例) s2 Singleton(别的名字) print(s1.name) # 测试单例不会被第二次初始化覆盖综合小案例把构造、析构、property、私有属性、单例结合的简易配置类class AppConfig: _instance None _init_done False def __new__(cls): if cls._instance is None: cls._instance super().__new__(cls) return cls._instance def __init__(self): if not self._init_done: self.__port 8080 self._init_done True property def port(self): return self.__port port.setter def port(self,val): if 1024 val 65535: self.__port val else: raise ValueError(端口号范围1024~65535) def __del__(self): print(配置对象销毁释放资源) cfg1 AppConfig() cfg2 AppConfig() print(cfg1 is cfg2) print(cfg1.port) cfg1.port 9000 print(cfg2.port)总结__init__构造函数对象初始化__del__析构函数对象销毁时调用不建议强依赖。property装饰器将方法伪装属性实现读写校验是 Python 封装的最佳实践。访问权限公有name、保护_name、私有__name靠命名约定私有本质是名字改写。单例模式重写__new__实现唯一实例注意__init__会重复执行的坑。