Python中有哪些特殊方法
# Python中有哪些特殊方法
## 目錄
1. [特殊方法概述](#特殊方法概述)
2. [對象生命周期相關方法](#對象生命周期相關方法)
3. [數值運算相關方法](#數值運算相關方法)
4. [類型轉換方法](#類型轉換方法)
5. [容器類型方法](#容器類型方法)
6. [屬性訪問控制方法](#屬性訪問控制方法)
7. [可調用對象方法](#可調用對象方法)
8. [上下文管理方法](#上下文管理方法)
9. [描述符協議方法](#描述符協議方法)
10. [比較操作相關方法](#比較操作相關方法)
11. [其他重要特殊方法](#其他重要特殊方法)
12. [實際應用案例](#實際應用案例)
13. [總結](#總結)
## 特殊方法概述
Python中的特殊方法(Special Methods),也稱為魔術方法(Magic Methods)或雙下方法(Dunder Methods),是以雙下劃線開頭和結尾的方法。這些方法允許開發者自定義類的行為,使其能夠與Python內置的操作符和函數無縫集成。
```python
class Example:
def __init__(self, value):
self.value = value
def __str__(self):
return f"Example with value: {self.value}"
特殊方法的主要特點:
- 由Python解釋器自動調用
- 實現特定的語言功能
- 命名遵循__xxx__
模式
- 不可直接調用(除非明確知道其用途)
對象生命周期相關方法
__new__
和 __init__
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating instance")
instance = super().__new__(cls)
return instance
def __init__(self, value):
print("Initializing instance")
self.value = value
__new__
: 負責實例創建(類方法)
__init__
: 負責實例初始化
- 關系:
__new__
返回實例 → __init__
初始化該實例
__del__
class Resource:
def __del__(self):
print("Cleaning up resources")
- 對象被垃圾回收時調用
- 不應用于重要資源清理(時機不確定)
- 建議使用上下文管理器或顯式清理方法
數值運算相關方法
基本算術運算
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
方法 |
操作符 |
描述 |
__add__ |
+ |
加法 |
__sub__ |
- |
減法 |
__mul__ |
* |
乘法 |
__truediv__ |
/ |
真除法 |
__floordiv__ |
// |
地板除 |
反向運算和就地運算
class Vector:
def __radd__(self, other):
return self.__add__(other)
def __iadd__(self, other):
self.x += other.x
self.y += other.y
return self
- 反向方法(如
__radd__
):當左操作數不支持操作時調用
- 就地方法(如
__iadd__
):實現+=
等操作
類型轉換方法
基本類型轉換
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
def __int__(self):
return int(self.celsius)
def __float__(self):
return float(self.celsius)
方法 |
調用方式 |
__bool__ |
bool(obj) |
__int__ |
int(obj) |
__float__ |
float(obj) |
__complex__ |
complex(obj) |
字符串表示
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Point({self.x}, {self.y})"
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
__str__
: 用戶友好字符串(str()和print())
__repr__
: 開發者友好字符串(repr()和交互式解釋器)
__format__
: 支持格式化字符串(format()和f-string)
容器類型方法
序列協議方法
class MyList:
def __init__(self, data):
self.data = list(data)
def __getitem__(self, index):
return self.data[index]
def __len__(self):
return len(self.data)
def __contains__(self, item):
return item in self.data
方法 |
操作 |
__len__ |
len(obj) |
__getitem__ |
obj[index] |
__setitem__ |
obj[index] = value |
__delitem__ |
del obj[index] |
__contains__ |
item in obj |
映射類型方法
class MyDict:
def __keys__(self):
return list(self.data.keys())
def __getitem__(self, key):
return self.data[key]
def __setitem__(self, key, value):
self.data[key] = value
屬性訪問控制方法
基本屬性訪問
class Person:
def __getattribute__(self, name):
print(f"Accessing {name}")
return super().__getattribute__(name)
def __setattr__(self, name, value):
print(f"Setting {name} = {value}")
super().__setattr__(name, value)
def __delattr__(self, name):
print(f"Deleting {name}")
super().__delattr__(name)
方法 |
調用場景 |
__getattr__ |
屬性不存在時 |
__getattribute__ |
所有屬性訪問 |
__setattr__ |
屬性賦值時 |
__delattr__ |
刪除屬性時 |
可調用對象方法
class Adder:
def __init__(self, n):
self.n = n
def __call__(self, x):
return self.n + x
add5 = Adder(5)
print(add5(10)) # 輸出15
__call__
: 使實例可像函數一樣調用
- 應用場景:裝飾器類、狀態保持函數
上下文管理方法
class FileHandler:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
if exc_type:
print(f"Exception handled: {exc_val}")
__enter__
: 進入上下文時調用
__exit__
: 離開上下文時調用
- 支持
with
語句
描述符協議方法
class ValidatedAttribute:
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not isinstance(value, int):
raise TypeError("Expected int")
instance.__dict__[self.name] = value
方法 |
描述 |
__get__ |
獲取屬性值時調用 |
__set__ |
設置屬性值時調用 |
__delete__ |
刪除屬性時調用 |
比較操作相關方法
class Money:
def __init__(self, amount, currency):
self.amount = amount
self.currency = currency
def __eq__(self, other):
return (self.amount == other.amount and
self.currency == other.currency)
def __lt__(self, other):
if self.currency != other.currency:
raise ValueError("Cannot compare different currencies")
return self.amount < other.amount
方法 |
操作符 |
反向方法 |
__eq__ |
== |
|
__ne__ |
!= |
|
__lt__ |
< |
__gt__ |
__le__ |
<= |
__ge__ |
其他重要特殊方法
類創建控制
class Meta(type):
def __new__(cls, name, bases, namespace):
print(f"Creating class {name}")
return super().__new__(cls, name, bases, namespace)
class MyClass(metaclass=Meta):
pass
__new__
: 控制類創建過程
__init_subclass__
: 子類初始化時調用
異步支持
class AsyncReader:
async def __aenter__(self):
self.file = await aiofiles.open(...)
return self
async def __aexit__(self, *args):
await self.file.close()
__await__
: 實現可等待對象
__aiter__
, __anext__
: 異步迭代
__aenter__
, __aexit__
: 異步上下文管理器
實際應用案例
實現向量類
class Vector:
def __init__(self, *components):
self.components = components
def __add__(self, other):
if len(self.components) != len(other.components):
raise ValueError("Vectors must be same dimension")
new_components = [
x + y for x, y in zip(self.components, other.components)
]
return Vector(*new_components)
def __mul__(self, scalar):
if isinstance(scalar, (int, float)):
return Vector(*[x * scalar for x in self.components])
raise TypeError("Can only multiply by scalar")
def __abs__(self):
return sum(x**2 for x in self.components) ** 0.5
def __str__(self):
return f"Vector{self.components}"
實現上下文管理器
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
self.end = time.time()
self.elapsed = self.end - self.start
print(f"Elapsed time: {self.elapsed:.2f} seconds")
# 使用示例
with Timer() as t:
time.sleep(1.5)
總結
Python的特殊方法提供了強大的能力來定制類的行為,使其能夠與Python語言結構無縫集成。關鍵要點:
- 特殊方法實現了操作符重載、類型轉換、容器行為等核心功能
- 命名約定為雙下劃線開頭和結尾
- 由Python解釋器自動調用
- 合理使用可以創建直觀、Pythonic的API
- 過度使用可能導致代碼難以理解
掌握這些特殊方法是成為Python高級開發者的重要一步,它們使得自定義類型能夠像內置類型一樣自然工作。
# 最終示例:綜合使用多個特殊方法
class Polynomial:
def __init__(self, coefficients):
self.coeffs = coefficients
def __call__(self, x):
return sum(coeff * (x ** i)
for i, coeff in enumerate(self.coeffs))
def __add__(self, other):
max_len = max(len(self.coeffs), len(other.coeffs))
new_coeffs = [
(self.coeffs[i] if i < len(self.coeffs) else 0) +
(other.coeffs[i] if i < len(other.coeffs) else 0)
for i in range(max_len)
]
return Polynomial(new_coeffs)
def __str__(self):
terms = []
for i, coeff in enumerate(self.coeffs):
if coeff == 0:
continue
term = f"{coeff}"
if i > 0:
term += "x" + (f"^{i}" if i > 1 else "")
terms.append(term)
return " + ".join(reversed(terms)) or "0"
通過靈活組合這些特殊方法,可以創建出功能強大且易于使用的自定義類,這正是Python語言優雅和強大之處。
“`