第11章:高级特性
作为 Java 开发者,你已经熟悉了 Java 的高级特性。Python 也有许多强大的高级特性,本章将详细对比两种语言的高级特性。
11.1 装饰器
Java 装饰器
Java 使用设计模式中的装饰器模式,通过实现接口和包装对象来实现。
// 接口
interface Coffee {
double cost();
String description();
}
// 具体实现
class SimpleCoffee implements Coffee {
@Override
public double cost() {
return 5.0;
}
@Override
public String description() {
return "Simple Coffee";
}
}
// 装饰器
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
}
// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return coffee.cost() + 1.5;
}
@Override
public String description() {
return coffee.description() + " with Milk";
}
}
// 使用
Coffee coffee = new MilkDecorator(new SimpleCoffee());
System.out.println(coffee.description() + " costs " + coffee.cost());
Python 装饰器
Python 使用 @ 语法和函数闭包实现装饰器。
# 简单装饰器
def log_function(func):
"""日志装饰器"""
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@log_function
def add(a, b):
return a + b
print(add(3, 5))
# 带参数的装饰器
def repeat(n):
"""重复执行函数n次的装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
results = []
for i in range(n):
results.append(func(*args, **kwargs))
return results
return wrapper
return decorator
@repeat(3)
def greet(name):
return f"Hello, {name}!"
print(greet("Alice"))
# 类装饰器
class CountCalls:
"""统计函数调用次数的装饰器"""
def __init__(self, func):
self.func = func
self.calls = 0
def __call__(self, *args, **kwargs):
self.calls += 1
print(f"Call {self.calls} of {self.func.__name__}")
return self.func(*args, **kwargs)
@CountCalls
def say_hello(name):
return f"Hello, {name}!"
print(say_hello("Bob"))
print(say_hello("Charlie"))
对比:
| 特性 | Java | Python |
|---|---|---|
| 实现方式 | 设计模式(接口 + 包装类) | 函数闭包 + @ 语法 |
| 语法 | 显式包装对象 | 简洁的 @ 语法 |
| 灵活性 | 相对复杂 | 更灵活,支持参数 |
| 用途 | 主要用于扩展功能 | 广泛用于日志、缓存、权限等 |
11.2 生成器
Java 生成器
Java 8+ 引入了 Stream API,可以实现类似生成器的功能。
// 使用 Stream 生成序列
IntStream.range(1, 10)
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
// 自定义生成器
class FibonacciGenerator implements Iterator<Long> {
private long a = 0;
private long b = 1;
@Override
public boolean hasNext() {
return true; // 无限序列
}
@Override
public Long next() {
long result = a;
long next = a + b;
a = b;
b = next;
return result;
}
}
// 使用
FibonacciGenerator fib = new FibonacciGenerator();
for (int i = 0; i < 10; i++) {
System.out.println(fib.next());
}
Python 生成器
Python 使用 yield 语句实现生成器。
# 生成器函数
def fibonacci():
"""斐波那契数列生成器"""
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# 使用生成器
fib = fibonacci()
for i in range(10):
print(next(fib))
# 生成器表达式
squares = (x**2 for x in range(10))
for square in squares:
print(square)
# 生成器的优势:节省内存
# 对于大序列,生成器比列表更节省内存
def big_range(n):
for i in range(n):
yield i
# 即使 n 很大,也不会占用太多内存
for i in big_range(1000000):
if i % 100000 == 0:
print(i)
对比:
| 特性 | Java | Python |
|---|---|---|
| 实现方式 | Iterator 接口或 Stream API | yield 语句 |
| 语法 | 相对复杂 | 简洁的 yield 语法 |
| 内存效率 | Stream 较高效 | 生成器非常高效 |
| 用途 | 主要用于集合处理 | 广泛用于惰性计算 |
11.3 上下文管理器
Java 上下文管理器
Java 7+ 引入了 try-with-resources 语句。
// 使用 try-with-resources
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// 自定义 AutoCloseable 类
class Resource implements AutoCloseable {
public Resource() {
System.out.println("Resource created");
}
public void use() {
System.out.println("Resource used");
}
@Override
public void close() {
System.out.println("Resource closed");
}
}
// 使用
try (Resource resource = new Resource()) {
resource.use();
}
Python 上下文管理器
Python 使用 with 语句和 __enter__/__exit__ 方法实现上下文管理器。
# 使用内置上下文管理器
with open("example.txt", "r") as file:
content = file.read()
print(content)
# 文件自动关闭
# 自定义上下文管理器
class Timer:
def __enter__(self):
import time
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
import time
self.end = time.time()
print(f"Elapsed time: {self.end - self.start:.2f} seconds")
with Timer():
# 执行一些操作
import time
time.sleep(1)
# 使用 contextmanager 装饰器
from contextlib import contextmanager
@contextmanager
def temporary_file():
"""临时文件上下文管理器"""
import tempfile
temp = tempfile.NamedTemporaryFile(mode='w', delete=False)
try:
yield temp
finally:
import os
os.unlink(temp.name)
with temporary_file() as f:
f.write("Temporary data")
print(f"Temp file: {f.name}")
对比:
| 特性 | Java | Python |
|---|---|---|
| 实现方式 | AutoCloseable 接口 | __enter__/__exit__ 方法 |
| 语法 | try-with-resources | with 语句 |
| 灵活性 | 相对有限 | 更灵活,支持装饰器实现 |
| 用途 | 主要用于资源管理 | 广泛用于资源管理、事务等 |
11.4 类型提示
Java 类型系统
Java 是静态类型语言,编译时进行类型检查。
// 显式类型声明
String name = "Alice";
int age = 25;
List<String> names = new ArrayList<>();
// 方法参数和返回类型
public String greet(String name) {
return "Hello, " + name;
}
// 泛型
public class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
Python 类型提示
Python 3.5+ 引入了类型提示,是可选的。
# 类型提示
name: str = "Alice"
age: int = 25
names: list[str] = ["Alice", "Bob", "Charlie"]
# 函数类型提示
def greet(name: str) -> str:
return f"Hello, {name}"
# 泛型类型提示
from typing import List, Dict, Optional, Union, TypeVar, Generic
T = TypeVar('T')
class Box(Generic[T]):
def __init__(self, value: T):
self.value: T = value
def get_value(self) -> T:
return self.value
# 使用
box: Box[str] = Box("Hello")
print(box.get_value())
# 可选类型
def find_user(user_id: int) -> Optional[str]:
users = {1: "Alice", 2: "Bob"}
return users.get(user_id)
# 联合类型
def process_value(value: Union[int, str]) -> str:
return str(value)
对比:
| 特性 | Java | Python |
|---|---|---|
| 类型系统 | 静态类型,编译时检查 | 动态类型,类型提示是可选的 |
| 类型声明 | 必须 | 可选 |
| 泛型 | 支持 | 支持(通过 typing 模块) |
| 类型检查 | 编译时强制 | 运行时可选(使用 mypy) |
| 灵活性 | 相对严格 | 更灵活,类型提示不影响运行 |
11.5 异步编程
Java 异步编程
Java 使用 CompletableFuture 和 ExecutorService 实现异步编程。
// 使用 CompletableFuture
CompletableFuture.supplyAsync(() -> {
// 异步任务
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello";
}).thenAccept(result -> {
System.out.println("Result: " + result);
});
// 使用 ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<String> future = executor.submit(() -> {
// 异步任务
Thread.sleep(1000);
return "Hello";
});
// 获取结果
try {
String result = future.get();
System.out.println("Result: " + result);
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
Python 异步编程
Python 3.5+ 引入了 async 和 await 关键字。
import asyncio
# 异步函数
async def greet(name):
print(f"Hello, {name}!")
await asyncio.sleep(1) # 模拟耗时操作
print(f"Goodbye, {name}!")
return f"Greeted {name}"
# 异步主函数
async def main():
# 顺序执行
result1 = await greet("Alice")
result2 = await greet("Bob")
print(f"Results: {result1}, {result2}")
# 并发执行
tasks = [greet("Charlie"), greet("David")]
results = await asyncio.gather(*tasks)
print(f"Concurrent results: {results}")
# 运行异步代码
asyncio.run(main())
# 异步IO
import aiohttp
async def fetch_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = ["https://api.github.com", "https://api.example.com"]
tasks = [fetch_url(url) for url in urls]
responses = await asyncio.gather(*tasks)
for url, response in zip(urls, responses):
print(f"{url} status: {len(response)} bytes")
asyncio.run(main())
对比:
| 特性 | Java | Python |
|---|---|---|
| 实现方式 | CompletableFuture, ExecutorService | async/await 关键字 |
| 语法 | 相对复杂 | 简洁的 async/await 语法 |
| 并发模型 | 多线程 | 单线程事件循环(协程) |
| 适用场景 | CPU 密集型任务 | IO 密集型任务 |
| 库支持 | CompletableFuture | asyncio, aiohttp 等 |
11.6 元编程
Java 元编程
Java 使用反射和注解实现元编程。
// 反射
Class<?> clazz = String.class;
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
// 注解
@interface MyAnnotation {
String value();
}
@MyAnnotation("test")
class MyClass {
@MyAnnotation("method")
public void myMethod() {
}
}
// 读取注解
MyAnnotation classAnnotation = MyClass.class.getAnnotation(MyAnnotation.class);
System.out.println(classAnnotation.value()); // test
Method method = MyClass.class.getMethod("myMethod");
MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);
System.out.println(methodAnnotation.value()); // method
Python 元编程
Python 使用装饰器、元类和反射实现元编程。
# 反射
def greet(name):
return f"Hello, {name}!"
print(greet.__name__) # greet
print(greet.__doc__) # None
print(dir(greet)) # 查看所有属性和方法
# 装饰器(见前面的例子)
# 元类
class Meta(type):
def __new__(mcs, name, bases, dct):
# 在类创建时修改
dct['class_variable'] = 'value'
return super().__new__(mcs, name, bases, dct)
class MyClass(metaclass=Meta):
pass
print(MyClass.class_variable) # value
# 动态创建类
MyDynamicClass = type('MyDynamicClass', (object,), {'x': 1, 'y': 2})
instance = MyDynamicClass()
print(instance.x, instance.y) # 1 2
# 猴子补丁
class Person:
def greet(self):
return "Hello"
# 动态修改方法
Person.greet = lambda self: "Hi"
p = Person()
print(p.greet()) # Hi
对比:
| 特性 | Java | Python |
|---|---|---|
| 元编程方式 | 反射、注解 | 装饰器、元类、反射 |
| 灵活性 | 相对有限 | 非常灵活 |
| 语法 | 相对复杂 | 简洁直观 |
| 运行时修改 | 有限 | 强大的运行时修改能力 |
| 用途 | 框架开发、依赖注入 | 框架开发、元数据处理 |
11.7 练习
- 装饰器练习:创建一个装饰器,缓存函数的返回值
- 生成器练习:创建一个生成器,生成质数序列
- 上下文管理器练习:创建一个上下文管理器,管理数据库连接
- 类型提示练习:为一个函数添加完整的类型提示
- 异步编程练习:使用 asyncio 并发获取多个 URL 的内容
- 元编程练习:使用元类创建一个单例类
11.8 小结
- Python 的装饰器比 Java 的装饰器模式更简洁、更强大
- Python 的生成器使用
yield语句,比 Java 的Iterator更直观 - Python 的上下文管理器使用
with语句,比 Java 的 try-with-resources 更灵活 - Python 的类型提示是可选的,比 Java 的静态类型系统更灵活
- Python 的异步编程使用
async/await,比 Java 的CompletableFuture更简洁 - Python 的元编程能力比 Java 更强大,支持运行时修改类和函数
通过本章的学习,你已经了解了 Java 和 Python 在高级特性上的主要区别。接下来,我们将学习 Python 的标准库与生态。