Python 高级编程指南

Python 高级编程指南

深入理解 Python 核心机制与高级特性

面向对象编程 (OOP)

类与对象

Python 是完全面向对象的语言,一切皆对象。类通过 class 关键字定义,对象是类的实例。

class Person:
    """人类的基本表示"""
    
    # 类属性 (所有实例共享)
    species = "Homo sapiens"
    
    def __init__(self, name, age):
        """初始化方法 (构造函数)"""
        self.name = name  # 实例属性
        self.age = age
    
    def greet(self):
        """实例方法"""
        return f"Hello, my name is {self.name} and I'm {self.age} years old."
    
    @classmethod
    def from_birth_year(cls, name, birth_year):
        """类方法 (替代构造函数)"""
        from datetime import datetime
        current_year = datetime.now().year
        return cls(name, current_year - birth_year)
    
    @staticmethod
    def is_adult(age):
        """静态方法 (与类相关但不访问实例或类)"""
        return age >= 18

# 创建实例
alice = Person("Alice", 30)
print(alice.greet())  # Hello, my name is Alice and I'm 30 years old.

# 使用类方法创建实例
bob = Person.from_birth_year("Bob", 1990)
print(bob.greet())

# 访问类属性
print(f"We are all {Person.species}")

继承与多态

Python 支持单继承和多继承。子类可以重写父类的方法实现多态。

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("Subclass must implement this method")

class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

# 多态示例
animals = [Dog("Rex"), Cat("Mittens")]
for animal in animals:
    print(animal.speak())

# 多重继承示例
class A:
    def method(self):
        print("A method")

class B:
    def method(self):
        print("B method")

class C(A, B):
    pass

c = C()
c.method()  # 输出 "A method" (方法解析顺序 MRO)
方法解析顺序 (MRO): Python 使用 C3 线性化算法确定多继承时的方法调用顺序,可以通过 ClassName.__mro__ 查看。

魔术方法与操作符重载

Python 通过特殊方法 (双下划线方法) 实现操作符重载和其他特殊行为。

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)
    
    def __mul__(self, scalar):
        """重载 * 操作符 (向量与标量相乘)"""
        return Vector(self.x * scalar, self.y * scalar)
    
    def __repr__(self):
        """对象的官方字符串表示"""
        return f"Vector({self.x}, {self.y})"
    
    def __len__(self):
        """重载 len() 函数 (返回向量的模)"""
        return int((self.x**2 + self.y**2)**0.5)
    
    def __getitem__(self, index):
        """重载索引操作"""
        if index == 0:
            return self.x
        elif index == 1:
            return self.y
        else:
            raise IndexError("Vector index out of range")

v1 = Vector(2, 4)
v2 = Vector(1, 3)
print(v1 + v2)  # Vector(3, 7)
print(v1 * 3)   # Vector(6, 12)
print(len(v1))  # 4 (2的平方加4的平方开根号)

装饰器 (Decorators)

函数装饰器

装饰器是修改其他函数行为的函数,使用 @decorator 语法。它们是 Python 中强大的元编程工具。

def simple_decorator(func):
    """一个简单的装饰器,在函数调用前后打印信息"""
    def wrapper(*args, **kwargs):
        print(f"Before calling {func.__name__}")
        result = func(*args, **kwargs)
        print(f"After calling {func.__name__}")
        return result
    return wrapper

@simple_decorator
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")
# 输出:
# Before calling greet
# Hello, Alice!
# After calling greet

带参数的装饰器

装饰器可以接受参数,这需要额外的一层嵌套。

def repeat(num_times):
    """装饰器工厂,返回一个装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(num_times=3)
def say_hello():
    print("Hello!")

say_hello()
# 输出:
# Hello!
# Hello!
# Hello!

类装饰器

装饰器也可以应用于类,修改或扩展类的行为。

def singleton(cls):
    """单例装饰器,确保类只有一个实例"""
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

@singleton
class Database:
    def __init__(self):
        print("Database connection established")

db1 = Database()  # 输出: Database connection established
db2 = Database()
print(db1 is db2)  # 输出: True (同一个实例)

内置装饰器

Python 提供了一些有用的内置装饰器。

from functools import wraps, lru_cache

def log_decorator(func):
    """保留原始函数元信息的装饰器"""
    @wraps(func)  # 使用 wraps 保留原始函数的 __name__, __doc__ 等
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@log_decorator
def add(a, b):
    """Add two numbers"""
    return a + b

print(add.__name__)  # 输出 "add" (而不是 "wrapper")
print(add.__doc__)   # 输出 "Add two numbers"

# 缓存装饰器 (Memoization)
@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# 第一次计算会递归调用
print(fibonacci(10))  # 55
# 后续调用相同参数会直接从缓存返回
print(fibonacci(10))  # 立即返回 55

生成器与协程

生成器函数

生成器是特殊的迭代器,使用 yield 关键字实现。它们按需生成值,节省内存。

def countdown(n):
    """生成器函数示例"""
    print("Starting countdown from", n)
    while n > 0:
        yield n  # 每次迭代返回 n 的值
        n -= 1
    print("Countdown finished!")

# 创建生成器对象
cd = countdown(3)

# 迭代生成器
for num in cd:
    print(num)

# 输出:
# Starting countdown from 3
# 3
# 2
# 1
# Countdown finished!

# 生成器表达式 (类似列表推导,但惰性求值)
squares = (x*x for x in range(10))
print(next(squares))  # 0
print(next(squares))  # 1
print(sum(squares))   # 剩余平方数的和: 284

协程与 yield

生成器可以转换为协程,使用 yield 接收值,实现双向通信。

def coroutine_example():
    """协程示例"""
    print("Coroutine started")
    while True:
        received = yield  # 接收值
        print("Received:", received)

coro = coroutine_example()
next(coro)  # 启动协程 (执行到第一个 yield)
coro.send("Hello")  # 输出: Received: Hello
coro.send("World")  # 输出: Received: World
coro.close()  # 关闭协程

async/await

Python 3.5+ 引入了原生协程语法 async/await,用于异步编程。

import asyncio

async def fetch_data():
    """模拟异步获取数据"""
    print("Start fetching")
    await asyncio.sleep(2)  # 模拟 I/O 操作
    print("Done fetching")
    return {"data": 123}

async def print_numbers():
    """打印数字"""
    for i in range(10):
        print(i)
        await asyncio.sleep(0.25)

async def main():
    """主协程"""
    task1 = asyncio.create_task(fetch_data())
    task2 = asyncio.create_task(print_numbers())
    
    # 等待任务1完成并获取结果
    data = await task1
    print("Received data:", data)
    
    # 等待任务2完成
    await task2

# 运行事件循环
asyncio.run(main())
注意: 异步编程模型与同步编程有显著不同,需要理解事件循环、任务调度等概念。

上下文管理器

with 语句

上下文管理器通过 with 语句管理资源,确保资源被正确释放。

# 文件操作的标准用法
with open('example.txt', 'w') as f:
    f.write("Hello, World!")
# 文件会在 with 块结束后自动关闭

# 自定义上下文管理器类
class DatabaseConnection:
    def __init__(self, db_name):
        self.db_name = db_name
    
    def __enter__(self):
        print(f"Connecting to {self.db_name}")
        self.connection = "Active Connection"  # 模拟连接
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"Closing connection to {self.db_name}")
        self.connection = None
        if exc_type is not None:
            print(f"An error occurred: {exc_val}")
        return True  # 抑制异常

with DatabaseConnection("MyDB") as db:
    print(f"Using connection: {db.connection}")
    # 如果这里发生异常,__exit__ 会处理
    # 1 / 0  # 取消注释会触发异常,但会被抑制

contextlib 模块

contextlib 模块提供了创建上下文管理器的实用工具。

from contextlib import contextmanager, redirect_stdout
import io

# 使用生成器函数创建上下文管理器
@contextmanager
def temporary_change(obj, attr, new_value):
    """临时修改对象属性"""
    old_value = getattr(obj, attr)
    setattr(obj, attr, new_value)
    try:
        yield
    finally:
        setattr(obj, attr, old_value)

class MyClass:
    value = 10

obj = MyClass()
print("Before:", obj.value)  # 10
with temporary_change(obj, 'value', 20):
    print("During:", obj.value)  # 20
print("After:", obj.value)  # 10

# 重定向标准输出
f = io.StringIO()
with redirect_stdout(f):
    print("This goes to the StringIO")
print("This goes to the console")
print("Captured:", f.getvalue())

元类 (Metaclasses)

理解元类

元类是类的类,控制类的创建行为。Python 中所有类都是 type 的实例。

# 使用 type 动态创建类
MyClass = type('MyClass', (), {'x': 10})

obj = MyClass()
print(obj.x)  # 10

# 等价于
class MyClass:
    x = 10

# 查看类的类型
print(type(MyClass))  # 
print(type(obj))      # 

自定义元类

通过继承 type 创建自定义元类,可以干预类的创建过程。

class Meta(type):
    """一个简单的元类,自动将方法名转为大写"""
    def __new__(cls, name, bases, namespace):
        # 创建类前修改命名空间
        uppercase_attrs = {
            attr.upper(): val 
            for attr, val in namespace.items()
            if not attr.startswith('__')
        }
        return super().__new__(cls, name, bases, uppercase_attrs)

class MyClass(metaclass=Meta):
    x = 10
    
    def my_method(self):
        print("Method called")

obj = MyClass()
print(obj.X)  # 10 (属性名被转为大写)
obj.MY_METHOD()  # Method called (方法名被转为大写)

# 元类的实际应用场景:
# 1. API 验证
# 2. ORM 框架
# 3. 自动注册子类
# 4. 接口实现检查
注意: 元类是 Python 的高级特性,大多数情况下可以通过装饰器或类装饰器实现相同功能,代码会更清晰。

并发编程

多线程

Python 的 threading 模块用于线程管理,但由于 GIL (全局解释器锁),多线程不适合 CPU 密集型任务。

import threading
import time

def worker(num):
    """线程工作函数"""
    print(f"Worker {num} started")
    time.sleep(1)
    print(f"Worker {num} finished")

threads = []
for i in range(3):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

print("All threads completed")

# 线程同步
counter = 0
lock = threading.Lock()

def increment():
    global counter
    with lock:  # 使用锁确保原子操作
        current = counter
        time.sleep(0.1)  # 模拟处理时间
        counter = current + 1

threads = [threading.Thread(target=increment) for _ in range(10)]
for t in threads:
    t.start()
for t in threads:
    t.join()

print(f"Final counter value: {counter}")  # 正确输出 10

多进程

multiprocessing 模块绕过 GIL 限制,适合 CPU 密集型任务。

from multiprocessing import Process, Queue
import os

def square(numbers, q):
    """进程工作函数"""
    for num in numbers:
        q.put(num * num)

if __name__ == '__main__':
    numbers = range(5)
    q = Queue()
    
    p = Process(target=square, args=(numbers, q))
    p.start()
    p.join()
    
    while not q.empty():
        print(q.get())  # 0, 1, 4, 9, 16

# 进程池
from multiprocessing import Pool

def cube(x):
    return x * x * x

if __name__ == '__main__':
    with Pool(processes=4) as pool:
        results = pool.map(cube, range(10))
    print(results)  # [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]

异步 I/O

asyncio 模块适合 I/O 密集型任务,使用单线程事件循环实现高并发。

import asyncio

async def fetch_url(url):
    """模拟异步获取 URL 内容"""
    print(f"Fetching {url}")
    await asyncio.sleep(1)  # 模拟网络请求
    print(f"Finished {url}")
    return f"{url}"

async def main():
    """主协程"""
    urls = [
        "https://example.com",
        "https://python.org",
        "https://github.com"
    ]
    
    # 同时运行多个协程
    tasks = [fetch_url(url) for url in urls]
    results = await asyncio.gather(*tasks)
    print("All URLs fetched:", results)

asyncio.run(main())

# 输出:
# Fetching https://example.com
# Fetching https://python.org
# Fetching https://github.com
# (1秒后)
# Finished https://example.com
# Finished https://python.org
# Finished https://github.com
# All URLs fetched: ['https://example.com', ...]
并发选择指南:
- CPU 密集型: 多进程
- I/O 密集型: 异步 I/O 或多线程
- 混合型: 组合使用 (如 asyncio + 进程池)

类型注解

基本类型注解

Python 3.5+ 支持类型注解,通过 typing 模块增强代码可读性和 IDE 支持。

from typing import List, Dict, Tuple, Set, Optional, Union, Any, Callable

# 变量注解
name: str = "Alice"
age: int = 30
is_active: bool = True

# 函数注解
def greet(name: str) -> str:
    return f"Hello, {name}"

# 容器类型
numbers: List[int] = [1, 2, 3]
person: Dict[str, Union[str, int]] = {"name": "Bob", "age": 25}
coordinates: Tuple[float, float] = (10.5, 20.3)
unique_numbers: Set[int] = {1, 2, 3}

# 可选类型 (可能为 None)
maybe_name: Optional[str] = None

# 回调函数类型
callback: Callable[[int, str], bool] = lambda x, s: len(s) > x

# 任意类型
anything: Any = 42
anything = "Now a string"  # 合法

# 类型别名
UserId = int
user_id: UserId = 12345

高级类型

Python 3.9+ 引入了更简洁的类型注解语法,并支持更多高级类型。

# Python 3.9+ 原生容器类型注解
numbers: list[int] = [1, 2, 3]  # 替代 List[int]
person: dict[str, str | int] = {"name": "Bob", "age": 25}  # 替代 Dict[str, Union[str, int]]

# 字面量类型
from typing import Literal
Mode = Literal["r", "rb", "w", "wb"]
def open_file(file: str, mode: Mode) -> None:
    pass

# 可调用对象
from typing import Callable
def apply_func(func: Callable[[int, int], float], a: int, b: int) -> float:
    return func(a, b)

# 泛型
from typing import TypeVar, Generic
T = TypeVar('T')

class Box(Generic[T]):
    def __init__(self, content: T):
        self.content = content
    
    def get(self) -> T:
        return self.content

int_box: Box[int] = Box(123)
str_box: Box[str] = Box("hello")

类型检查工具

使用 mypy 等工具进行静态类型检查。

# 安装 mypy
pip install mypy

# 检查你的 Python 文件
mypy your_script.py
类型注解的好处:
- 提高代码可读性和可维护性
- 更好的 IDE 支持 (自动补全、错误检测)
- 早期发现潜在错误
- 便于大型项目协作

继续深入 Python 世界

你已经掌握了 Python 的高级特性!接下来可以探索更专业的领域:

数据科学

NumPy, Pandas, Matplotlib, SciPy

Web 开发

Django, Flask, FastAPI, ASGI

机器学习

Scikit-learn, TensorFlow, PyTorch

互动区域

登录后可以点赞此内容

参与互动

登录后可以点赞和评论此内容,与作者互动交流