Python 魔术方法深度解析与面向对象实践
面向对象基础与动态特性
Python 中通过 class 关键字构建自定义类型。实例化时,解释器自动触发构造逻辑完成对象初始化。
class Human:
def __init__(self, nickname):
self.nickname = nickname
def display(self):
print(f"当前对象: {self.nickname}")
if __name__ == '__main__':
h = Human("Alice")
h.display()
运行时属性注入
Python 允许在实例创建后动态挂载属性,但该属性仅属于被操作的实例,不会扩散到其他对象。
class Human:
def __init__(self):
pass
if __name__ == '__main__':
h = Human()
h.nickname = "Alice"
print(h.nickname)
组合模式
类的成员可以是另一个类的实例,形成"has-a"关系。
class Engine:
def __init__(self, power):
self.power = power
class Vehicle:
def __init__(self, engine):
self.engine = engine
v8 = Engine(450)
car = Vehicle(v8)
核心魔术方法详解
| 方法 | 触发场景 | 备注 |
|---|---|---|
__init__ | 实例化后初始化 | 非构造方法,构造由 __new__ 负责 |
__str__ | str()、print() | 面向用户,可读性强 |
__repr__ | repr()、交互式解释器 | 面向开发者,应能 eval(repr(obj)) == obj |
__del__ | 实例引用计数归零 | 用于资源释放,不保证立即执行 |
__len__ | len() | 返回非负整数 |
__getitem__ | 索引、切片访问 | obj[key] |
__getattr__ | 属性查找失败 | 避免无限递归 |
__setitem__ | 索引赋值 | 支持 random.shuffle 等操作 |
__enter__/__exit__ | with 语句 | 上下文管理协议 |
class Student:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Student({self.name!r})"
def __repr__(self):
return f"Student(name={self.name!r})"
def __len__(self):
return len(self.name)
def __getitem__(self, idx):
return self.name[idx]
if __name__ == '__main__':
s = Student("Bob")
print(s) # Student('Bob')
print(len(s)) # 3
print(s[0]) # B
运算符重载机制
算术运算符
| 运算符 | 正向 | 反向 | 就地 |
|---|---|---|---|
| + | __add__ | __radd__ | __iadd__ |
| - | __sub__ | __rsub__ | __isub__ |
| * | __mul__ | __rmul__ | __imul__ |
| / | __truediv__ | __rtruediv__ | __itruediv__ |
| // | __floordiv__ | __rfloordiv__ | __ifloordiv__ |
| % | __mod__ | __rmod__ | __imod__ |
| ** | __pow__ | __rpow__ | __ipow__ |
| @ | __matmul__ | __rmatmul__ | __imatmul__ |
比较运算符
| 运算符 | 方法 | 默认行为 |
|---|---|---|
| == | __eq__ | 基于 id() 判断 |
| != | __ne__ | 取反 __eq__ 结果 |
| < | __lt__ | 抛出 TypeError |
| <= | __le__ | 抛出 TypeError |
| > | __gt__ | 抛出 TypeError |
| >= | __ge__ | 抛出 TypeError |
一元运算符重载应返回新对象,而非修改操作数本身。
class Vector:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __repr__(self):
return f"Vector({self.x!r}, {self.y!r})"
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __call__(self):
print(f"向量坐标: ({self.x}, {self.y})")
v1 = Vector(2, 3)
v2 = Vector(1, 1)
print(v1 + v2) # Vector(3, 4)
print(v1 * 3) # Vector(6, 9)
v1() # 向量坐标: (2, 3)
访问控制与封装
命名约定与可见性
class Employee:
company = "TechCorp" # 类属性,公有
def __init__(self, name, salary):
self.name = name
self.__salary = salary # 名称改写为 _Employee__salary
def get_salary(self):
return self.__salary
def set_salary(self, value):
if value > 0:
self.__salary = value
def __audit(self): # 私有方法
print("内部审计中...")
def public_audit(self):
self.__audit()
e = Employee("Tom", 5000)
print(e.name) # Tom
print(e.get_salary()) # 5000
e.set_salary(6000)
继承体系设计
单继承与属性继承
class Base:
def __init__(self, value):
self.value = value
self.__hidden = 100
class Derived(Base):
def __init__(self, value, extra):
super().__init__(value) # 显式调用父类初始化
self.extra = extra
d = Derived(10, 20)
print(d.value) # 10
print(d._Base__hidden) # 100 (名称改写访问,不推荐)
多继承与 MRO
class A:
def __init__(self):
print("A init")
super().__init__()
class B(A):
def __init__(self):
print("B init")
super().__init__()
class C(A):
def __init__(self):
print("C init")
super().__init__()
class D(B, C):
def __init__(self):
print("D init")
super().__init__()
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
d = D()
方法重写与扩展
class Logger:
def log(self, msg):
print(f"[INFO] {msg}")
class TimestampLogger(Logger):
def log(self, msg):
from datetime import datetime
super().log(f"{datetime.now()}: {msg}")
tl = TimestampLogger()
tl.log("系统启动")
多态与类方法
class Dog:
def speak(self):
print("汪汪")
class Cat:
def speak(self):
print("喵喵")
def animal_sound(creature):
creature.speak()
animal_sound(Dog()) # 汪汪
animal_sound(Cat()) # 喵喵
类方法与静态方法
class MathUtils:
PI = 3.14159
@classmethod
def circle_area(cls, radius):
return cls.PI * radius ** 2
@staticmethod
def is_positive(num):
return num > 0
print(MathUtils.circle_area(5)) # 78.53975
print(MathUtils.is_positive(-3)) # False
模块组织与导入
# utils.py
threshold = 10
def helper():
return "辅助功能"
class Tool:
pass
# main.py
import utils
from utils import Tool, helper
# 处理命名冲突
import utils as u
def helper():
pass
print(u.helper()) # 调用模块中的函数
Property 描述符
类属性方式
class Product:
def __init__(self):
self.__price = 0.0
def get_price(self):
return self.__price
def set_price(self, value):
if value >= 0:
self.__price = value
price = property(get_price, set_price)
p = Product()
p.price = 99.5
print(p.price)
装饰器方式(推荐)
class Product:
def __init__(self):
self.__price = 0.0
@property
def price(self):
return self.__price
@price.setter
def price(self, value):
if value >= 0:
self.__price = value
@price.deleter
def price(self):
del self.__price
p = Product()
p.price = 149.0
print(p.price)
魔术方法分类速查
| 类别 | 方法 |
|---|---|
| 字符串表示 | __repr__, __str__, __format__, __bytes__ |
| 数值转换 | __abs__, __bool__, __complex__, __int__, __float__, __hash__, __index__ |
| 集合模拟 | __len__, __getitem__, __setitem__, __delitem__, __contains__ |
| 迭代协议 | __iter__, __reversed__, __next__ |
| 可调用对象 | __call__ |
| 上下文管理 | __enter__, __exit__ |
| 生命周期 | __new__, __init__, __del__ |
| 属性管理 | __getattr__, __getattribute__, __setattr__, __delattr__, __dir__ |
| 描述符协议 | __get__, __set__, __delete__ |
