131 字
1 分钟
Python 函数与高级特性
一、装饰器
1.1 装饰器基础原理
import functools
# 装饰器本质:接收函数并返回增强函数的函数def timer(func): @functools.wraps(func) # 保留原函数元数据 def wrapper(*args, **kwargs): import time start = time.perf_counter() result = func(*args, **kwargs) end = time.perf_counter() print(f"{func.__name__} 耗时: {end - start:.4f}s") return result return wrapper
@timerdef slow_function(): import time time.sleep(1)
# 等价于:slow_function = timer(slow_function)1.2 带参数的装饰器
import functoolsimport time
# 带参数的装饰器:返回装饰器的函数def retry(max_attempts=3, delay=1): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): last_exception = None for attempt in range(max_attempts): try: return func(*args, **kwargs) except Exception as e: last_exception = e if attempt < max_attempts - 1: time.sleep(delay) raise last_exception return wrapper return decorator
@retry(max_attempts=3, delay=2)def unstable_api(): pass1.3 类装饰器
import functools
# 类装饰器:实现 __call__ 方法class CallCounter: def __init__(self, func): self.func = func self.count = 0 functools.update_wrapper(self, func)
def __call__(self, *args, **kwargs): self.count += 1 print(f"调用次数: {self.count}") return self.func(*args, **kwargs)
@CallCounterdef my_function(): pass
# 使用场景:缓存、计时、访问控制class Memoize: def __init__(self, func): self.func = func self.cache = {} functools.update_wrapper(self, func)
def __call__(self, *args): if args not in self.cache: self.cache[args] = self.func(*args) return self.cache[args]1.4 装饰器顺序
# 装饰器从下到上执行@decorator1 # 第2个执行@decorator2 # 第1个执行def func(): pass
# 等价于:func = decorator1(decorator2(func))二、生成器与迭代器
2.1 生成器函数
# 生成器函数:包含 yield 关键字def fibonacci(n): a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b
# 生成器对象gen = fibonacci(10)print(type(gen)) # <class 'generator'>
# 迭代获取值for value in gen: print(value)
# next() 获取gen = fibonacci(5)print(next(gen)) # 0print(next(gen)) # 1print(next(gen)) # 12.2 生成器表达式
# 生成器表达式:惰性求值gen = (x**2 for x in range(1000000)) # 不占满内存
# 列表推导式:立即求值lst = [x**2 for x in range(1000000)] # 占用大量内存
# 使用场景对比# 生成器适合:大数据处理、管道处理# 列表适合:小数据、需要多次迭代
# 链接生成器def numbers(): for i in range(10): yield i
def evens(): for i in numbers(): if i % 2 == 0: yield i
# itertools 生成器from itertools import count, cycle, chain, islice, takewhile
# 无限计数器for i in islice(count(10), 5): # 10, 11, 12, 13, 14 print(i)
# 循环for i in islice(cycle(['A', 'B']), 5): # A, B, A, B, A print(i)
# 链式迭代for i in chain([1, 2], ['a', 'b']): # 1, 2, a, b print(i)2.3 迭代器协议
# 迭代器必须实现 __iter__ 和 __next__class Counter: def __init__(self, n): self.n = n self.current = 0
def __iter__(self): return self
def __next__(self): if self.current >= self.n: raise StopIteration result = self.current self.current += 1 return result
for i in Counter(3): print(i) # 0, 1, 22.4 send() 与协程
# send() 与生成器通信def coroutine(): result = None while True: received = yield result result = received * 2
co = coroutine()next(co) # 启动协程print(co.send(10)) # 20print(co.send(5)) # 10
# close() 关闭协程co.close()
# throw() 抛出异常try: co.throw(ValueError, ValueError("error"))except ValueError: pass三、上下文管理器
3.1 类实现
# 实现 __enter__ 和 __exit__class DatabaseConnection: def __enter__(self): print("连接数据库") return self
def __exit__(self, exc_type, exc_val, exc_tb): print("关闭数据库连接") # 返回 True 抑制异常 return False
with DatabaseConnection() as db: print("使用数据库")
# 异常处理class SafeConnection: def __enter__(self): return self
def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is not None: print(f"异常: {exc_val}") return False # 不抑制异常 return True3.2 生成器实现
from contextlib import contextmanager
# 使用生成器实现上下文管理器@contextmanagerdef transaction(connection): print("开始事务") try: yield "tx_handle" print("提交事务") except Exception: print("回滚事务") raise
with transaction(conn) as tx: pass
# 清理操作@contextmanagerdef managed_resource(name): print(f"获取 {name}") try: yield name finally: print(f"释放 {name}")3.3 ExitStack 嵌套
from contextlib import ExitStack
# 多个上下文管理器with ExitStack() as stack: conn1 = stack.enter_context(db1_connection()) conn2 = stack.enter_context(db2_connection()) # 自动管理所有资源
# 条件进入with ExitStack() as stack: if needs_cache: cache = stack.enter_context(CacheManager()) if needs_logging: logger = stack.enter_context(Logger())四、偏函数与可调用对象
4.1 functools.partial
from functools import partial
# 固定函数的部分参数def power(base, exponent): return base ** exponent
square = partial(power, exponent=2)cube = partial(power, exponent=3)
print(square(5)) # 25print(cube(5)) # 125
# 常用场景:回调函数from functools import partial
def send_email(to, subject, body): print(f"To: {to}, Subject: {subject}")
send_to_alice = partial(send_email, to="alice@example.com")send_to_alice(subject="Hello", body="Hi!")4.2 可调用对象
# __call__ 使对象可像函数一样调用class Adder: def __init__(self, n): self.n = n
def __call__(self, x): return self.n + x
add5 = Adder(5)print(add5(10)) # 15print(callable(add5)) # True
# 使用场景:带状态的函数class RateLimiter: def __init__(self, max_calls, period): self.max_calls = max_calls self.period = period self.calls = []
def __call__(self, func): import time now = time.time() self.calls = [t for t in self.calls if now - t < self.period] if len(self.calls) >= self.max_calls: raise Exception("Rate limit exceeded") self.calls.append(now) return func()4.3 lru_cache 缓存
from functools import lru_cache
@lru_cache(maxsize=128)def expensive_computation(n): import time time.sleep(1) return n * n
# 缓存管理print(expensive_computation.cache_info())# CacheInfo(hits=0, misses=0, maxsize=128, currsize=0)
expensive_computation(10) # 计算expensive_computation(10) # 使用缓存print(expensive_computation.cache_info())# CacheInfo(hits=1, misses=1, maxsize=128, currsize=1)
# 清除缓存expensive_computation.cache_clear()五、元编程
5.1 动态创建类
# type() 动态创建类MyClass = type('MyClass', (object,), { 'x': 1, 'greet': lambda self: f"Hello, I'm {self.name}"})
# metaclass 控制类创建class ModelMeta(type): _registry = {}
def __new__(mcs, name, bases, attrs): cls = super().__new__(mcs, name, bases, attrs) mcs._registry[name] = cls return cls
class User(metaclass=ModelMeta): pass
print(ModelMeta._registry) # {'User': <class '__main__.User'>}5.2 getattr 与 getattribute
class Gateway: def __getattr__(self, name): # 属性不存在时调用 return f"calling {name}"
def __getattribute__(self, name): # 每次访问属性都调用 return f"intercepted {name}"
class Lazy: def __init__(self): self._data = {}
def __getattr__(self, name): print(f"Loading {name}") return self._data.get(name)
def __setattr__(self, name, value): if name == '_data': super().__setattr__(name, value) else: self._data[name] = value5.3 描述器协议
# 描述器:实现 __get__, __set__, __delete__class Property: def __init__(self, fget, fset=None): self.fget = fget self.fset = fset
def __get__(self, obj, objtype=None): return self.fget(obj)
def __set__(self, obj, value): if self.fset is None: raise AttributeError self.fset(obj, value)
class MyClass: @Property def value(self): return self._value
@value.setter def value(self, v): self._value = v支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时
相关文章 智能推荐
1
Python 并发与异步编程
面试 Python 并发编程——GIL 机制、asyncio 异步编程、threading 多线程、multiprocessing 多进程、协程与生成器。
2
Python 基础语法与核心概念
面试 Python 基础语法核心概念——数据类型对比、is 与 == 区别、深拷贝与浅拷贝、命名空间与作用域。
3
Kubernetes 安全与 RBAC
面试 Kubernetes 安全——RBAC 权限模型、Security Context、Pod Security Standards、网络策略、Secret 管理。
4
Python 面向对象与设计模式
面试 Python 面向对象编程——类变量与实例变量、继承与 MRO、常见设计模式、单例模式实现。
5
Python 内存管理与性能优化
面试 Python 内存管理——引用计数、垃圾回收机制、分代回收、内存泄漏、__slots__、性能优化技巧。






