黑魔法
上下文管理
from contextlib import contextmanager
@contextmanager
def managed_resource(value):
try:
print(f"Acquiring resource with {value}")
yield value
finally:
print("Releasing resource")
with managed_resource(42) as resource:
print(f"Using resource: {resource}")
# 输出:
# Acquiring resource with 42
# Using resource: 42
# Releasing resource
class MyContextManager:
def __enter__(self):
print("Entering context")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting context")
with MyContextManager() as cm:
print("Inside context")
# 输出:
# Entering context
# Inside context
# Exiting context
重定向标准输出
from contextlib import redirect_stdout
import io
f = io.StringIO()
with redirect_stdout(f):
print("This goes to the stringIO object")
output = f.getvalue()
print(output) # 输出: This goes to the stringIO object
生成器
def sub_generator():
yield 1
yield 2
def main_generator():
yield from sub_generator()
yield 3
yield 4
for value in main_generator():
print(value) # 输出: 1 2 3 4
函数缓存
from functools import lru_cache
# 可以缓存函数的结果,避免重复计算,适用于计算密集型或I/O密集型函数。
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 输出: 55
slots
class Person:
# 不能动态添加这两个属性外得属性
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
控制属性访问
class DynamicAttributes:
def __getattr__(self, name):
if name.startswith('custom_'):
return f"Custom attribute: {name}"
raise AttributeError(f"{name} is not a valid attribute")
def __setattr__(self, name, value):
if name.startswith('custom_'):
super().__setattr__(name, value)
else:
raise AttributeError(f"Cannot set attribute {name}")
dyn = DynamicAttributes()
print(dyn.custom_attribute) # 输出: Custom attribute: custom_attribute
dyn.custom_attribute = 42
print(dyn.custom_attribute) # 输出: 42
元编程
class MyMeta(type):
def __new__(cls, name, bases, dct):
print(f"Creating class {name}")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=MyMeta):
pass
# 输出: Creating class MyClass
自定义字典行为
class DefaultDict(dict):
# 自定义字典在访问不存在的键时的行为
def __missing__(self, key):
return f"Key {key} not found"
d = DefaultDict()
print(d['missing_key']) # 输出: Key missing_key not found
inspect
import inspect
def example_function():
pass
print(inspect.getsource(example_function)) # 输出: example_function 的源代码
print(inspect.signature(example_function)) # 输出: example_function 的签名
# 还可以获取函数得字符串代码等
枚举
from enum import Enum, auto
class Color(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
print(Color.RED) # 输出: Color.RED
print(Color.RED.value) # 输出: 1
数据类
from dataclasses import dataclass, field
# 简洁的方式来定义具有默认值和自动生成的特殊方法的类
@dataclass
class Person:
name: str
age: int
hobbies: list = field(default_factory=list)
alice = Person('Alice', 30)
print(alice) # 输出: Person(name='Alice', age=30, hobbies=[])
排列组合及生成
import itertools
# 组合函数
letters = ['a', 'b', 'c']
combinations = list(itertools.combinations(letters, 2))
print(combinations) # 输出: [('a', 'b'), ('a', 'c'), ('b', 'c')]
# 排列函数
permutations = list(itertools.permutations(letters, 2))
print(permutations) # 输出: [('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]
# 生成笛卡尔积
letters = ['a', 'b']
numbers = [1, 2]
numbers1 = [1, 2]
cartesian_product = list(itertools.product(letters, numbers,numbers1))
print(cartesian_product) # 输出: [('a', 1, 1), ('a', 1, 2), ('a', 2, 1), ('a', 2, 2), ('b', 1, 1), ('b', 1, 2), ('b', 2, 1), ('b', 2, 2)]
# 重复
repeated = itertools.repeat(10, 5)
print(list(repeated)) # 输出: [10, 10, 10, 10, 10]
# 循环
iterable = [1, 2, 3]
cycled = itertools.cycle(iterable)
for _ in range(10):
print(next(cycled), end=' ') # 输出: 1 2 3 1 2 3 1 2 3 1
# 链接
iter1 = [1, 2, 3]
iter2 = ['a', 'b', 'c']
result = list(itertools.chain(iter1, iter2))
print(result) # 输出: [1, 2, 3, 'a', 'b', 'c']
手动gc
import gc
gc.collect() # 手动触发垃圾回收
print(gc.get_count()) # 输出当前垃圾回收计数
print(gc.get_threshold()) # 输出垃圾回收阈值
对象格式化
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name}, {self.age} years old"
p = Person('Alice', 30)
print(str(p)) # 输出: Alice, 30 years old
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __format__(self, format_spec):
if format_spec == 'full':
return f"Name: {self.name}, Age: {self.age}"
elif format_spec == 'short':
return f"{self.name}"
else:
raise ValueError("Unknown format spec")
p = Person('Alice', 30)
print(f"{p:full}") # 输出: Name: Alice, Age: 30
print(f"{p:short}") # 输出: Alice
类运算
# __sub__ 方法
# 定义: __sub__(self, other)
# 用途: 定义对象自身作为左操作数时的减法行为。
# 调用时机: 当执行 a - b 时,如果 a 是一个定义了 __sub__ 方法的对象,Python 会调用 a.__sub__(b)。
# __rsub__ 方法
# 定义: __rsub__(self, other)
# 用途: 定义对象自身作为右操作数时的减法行为。
# 调用时机: 当执行 a - b 时,如果 a 没有定义 __sub__ 方法或 a.__sub__(b) 返回 NotImplemented,而 b 定义了 __rsub__ 方法,Python 会调用 b.__rsub__(a)。
class CustomNumber:
def __init__(self, value):
"""
初始化 CustomNumber 实例,设置其值。
"""
self.value = value
def __add__(self, other):
"""
定义加法操作符 `+` 的行为。
如果 other 是 CustomNumber 类型,则返回两个实例值相加的新 CustomNumber 实例。
"""
if isinstance(other, CustomNumber):
return CustomNumber(self.value + other.value)
return NotImplemented
def __radd__(self, other):
"""
定义反射加法操作符 `+` 的行为。
当左操作数不支持加法时,调用此方法。
"""
return CustomNumber(other + self.value)
def __sub__(self, other):
"""
定义减法操作符 `-` 的行为。
如果 other 是 CustomNumber 类型,则返回两个实例值相减的新 CustomNumber 实例。
"""
if isinstance(other, CustomNumber):
return CustomNumber(self.value - other.value)
return NotImplemented
def __rsub__(self, other):
"""
定义反射减法操作符 `-` 的行为。
当左操作数不支持减法时,调用此方法。
"""
return CustomNumber(other - self.value)
def __mul__(self, other):
"""
定义乘法操作符 `*` 的行为。
如果 other 是 CustomNumber 类型,则返回两个实例值相乘的新 CustomNumber 实例。
"""
if isinstance(other, CustomNumber):
return CustomNumber(self.value * other.value)
return NotImplemented
def __rmul__(self, other):
"""
定义反射乘法操作符 `*` 的行为。
当左操作数不支持乘法时,调用此方法。
"""
return CustomNumber(other * self.value)
def __truediv__(self, other):
"""
定义真除法操作符 `/` 的行为。
如果 other 是 CustomNumber 类型,则返回两个实例值相除的新 CustomNumber 实例。
"""
if isinstance(other, CustomNumber):
return CustomNumber(self.value / other.value)
return NotImplemented
def __rtruediv__(self, other):
"""
定义反射真除法操作符 `/` 的行为。
当左操作数不支持真除法时,调用此方法。
"""
return CustomNumber(other / self.value)
def __floordiv__(self, other):
"""
定义整除操作符 `//` 的行为。
如果 other 是 CustomNumber 类型,则返回两个实例值整除的新 CustomNumber 实例。
"""
if isinstance(other, CustomNumber):
return CustomNumber(self.value // other.value)
return NotImplemented
def __rfloordiv__(self, other):
"""
定义反射整除操作符 `//` 的行为。
当左操作数不支持整除时,调用此方法。
"""
return CustomNumber(other // self.value)
def __mod__(self, other):
"""
定义取模操作符 `%` 的行为。
如果 other 是 CustomNumber 类型,则返回两个实例值取模的新 CustomNumber 实例。
"""
if isinstance(other, CustomNumber):
return CustomNumber(self.value % other.value)
return NotImplemented
def __rmod__(self, other):
"""
定义反射取模操作符 `%` 的行为。
当左操作数不支持取模时,调用此方法。
"""
return CustomNumber(other % self.value)
def __pow__(self, other):
"""
定义幂运算操作符 `**` 的行为。
如果 other 是 CustomNumber 类型,则返回两个实例值幂运算的新 CustomNumber 实例。
"""
if isinstance(other, CustomNumber):
return CustomNumber(self.value ** other.value)
return NotImplemented
def __rpow__(self, other):
"""
定义反射幂运算操作符 `**` 的行为。
当左操作数不支持幂运算时,调用此方法。
"""
return CustomNumber(other ** self.value)
def __str__(self):
"""
返回 CustomNumber 实例的字符串表示。
"""
return str(self.value)
# 示例用法
a = CustomNumber(10)
b = CustomNumber(3)
print(a + b) # 输出: 13
print(a - b) # 输出: 7
print(a * b) # 输出: 30
print(a / b) # 输出: 3.3333333333333335
print(a // b) # 输出: 3
print(a % b) # 输出: 1
print(a ** b) # 输出: 1000
zip
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
zipped = zip(list1, list2)
print(list(zipped)) # 输出: [(1, 'a'), (2, 'b'), (3, 'c')]
for idx, (num, char) in enumerate(zip(list1, list2)):
print(f'Index: {idx}, Number: {num}, Character: {char}')
my_dict = dict(zip(list1, list2))
zipped = [(1, 'a'), (2, 'b'), (3, 'c')]
list1, list2 = zip(*zipped)
print(list1) # 输出: (1, 2, 3)
print(list2) # 输出: ('a', 'b', 'c')