从python简明教程学习软件开发流程&面向对象编程 以及python中装饰器的用法
开发软件的流程中各个阶段(Phase)
1.what/做什么->分析
2.how/怎么做->设计
3.do it/开始做->执行
4.test/测试->测试与修复错误
5.use/使用->操作或开发
6.maintain/维护->改进
添加功能就重复“开始做->测试->使用”的循环
Software is grown, not build.
学习资源
学习一门编程语言的最好方式就是编写大量代码,并阅读大量代码
A list of practical projects that anyone can solve in any programming language.
https://pragprog.com/
https://pymotw.com/2/contents.html
https://code.activestate.com/recipes/langs/python/
https://github.com/amontalenti/elements-of-python-style
https://github.com/realpython/discover-flask
https://pyvideo.org/
https://github.com/realpython/discover-flask
https://slott-softwarearchitect.blogspot.com/2013/06/python-big-picture-whats-roadmap.html
https://www.reddit.com/r/Python/comments/19dir2/whats_the_one_code_snippetpython_tricketc_did_you/
https://stackoverflow.com/questions/101268/hidden-features-of-python
面向对象编程 Object-oriented
一个类Class可以创建一个新的类型Type,对象Object是类的实例Instance
比如有类型int的变量,表明存储整数的变量是int类的实例(对象)
字段Field:属于对象或类的变量
类的方法Method:对象可以使用属于类的函数实现某些功能
类的属性Attribute=字段Field+方法Method
字段分为实例变量Instance Variables(是不共享的,不会对相同名称的产生影响)和类变量Class Variables(是不共享的,不会对相同名称的产生影响)
类方法里的函数必须添加一个参数再参数列表开头,但是不用在调用功能时为参数赋值,python会提供
特定变量引用的是对象本身,被赋予self的名称
__init__方法:会在类的对象被实例化的时候立刻运行,从而对任何想进行操作的目标对象做初始化操作
@classmethod装饰器,是调用包装器wrapper函数的快捷方式
- 继承Inheritance
可以想象成在类之间实现类型和子类型关系的工具
多态性polymorphism:在任何情况下,如果父类型希望,子类型都可以被替换,该对象可以被看做父类的实例 - 装饰器Decorators
装饰器是 Python 中一种强大的语法特性,它允许你在不修改原函数代码的情况下,动态地增强或修改函数的行为。你可以把它想象成“函数的包装纸”——在不改变原函数核心逻辑的前提下,为其添加额外功能。
核心理解
- 本质:装饰器本质上是一个高阶函数(接受函数作为参数,并返回新函数的函数)
- 语法糖:
@decorator是func = decorator(func)的简写形式 - 核心思想:通过闭包(closure)实现函数的嵌套和扩展
基础示例
def simple_decorator(func):
def wrapper():
print("Before function runs")
func() # 调用原函数
print("After function runs")
return wrapper
@simple_decorator
def say_hello():
print("Hello!")
say_hello()
# 输出:
# Before function runs
# Hello!
# After function runs
执行流程解析
- 当使用
@simple_decorator装饰say_hello时 - 相当于执行
say_hello = simple_decorator(say_hello) - 最终调用的
say_hello()实际上是调用wrapper()函数
进阶用法
1. 装饰带参数的函数
def decorator_with_args(func):
def wrapper(*args, **kwargs):
print("Received arguments:", args, kwargs)
return func(*args, **kwargs)
return wrapper
@decorator_with_args
def add(a, b):
return a + b
print(add(2, 3)) # 输出参数并返回5
2. 带参数的装饰器
def repeat(n_times): # 外层处理装饰器参数
def actual_decorator(func): # 真正的装饰器
def wrapper(*args, **kwargs):
for _ in range(n_times):
func(*args, **kwargs)
return wrapper
return actual_decorator
@repeat(3)
def greet(name):
print(f"Hello {name}!")
greet("Alice")
# 输出三次 Hello Alice!
3. 类装饰器
class ClassDecorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Class decorator called")
return self.func(*args, **kwargs)
@ClassDecorator
def my_func():
print("Original function")
my_func()
为什么要用装饰器?
- 代码复用:避免相同功能代码的重复编写
- 关注点分离:保持核心逻辑与辅助功能(如日志、计时、权限校验)的解耦
- 灵活扩展:动态添加/移除功能而不修改原代码
注意事项
- 使用
functools.wraps保留原函数元信息:
from functools import wraps
def good_decorator(func):
@wraps(func) # ← 保留原函数名称等属性
def wrapper():
# ...
return wrapper
实际应用场景
- 性能计时
- 日志记录
- 权限验证
- 缓存机制(如
@lru_cache) - 错误重试机制
- API路由(常见于Web框架如Flask)
1. 性能计时器
记录函数执行时间,用于性能调优
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
end = time.perf_counter()
print(f"{func.__name__} 耗时 {end - start:.4f}秒")
return result
return wrapper
@timer
def heavy_calculation(n):
return sum(i**2 for i in range(n))
heavy_calculation(10**6)
# 输出:heavy_calculation 耗时 0.3827秒
2. 权限验证
在Web开发中验证用户权限
from functools import wraps
def require_admin(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if not user.is_admin:
raise PermissionError("需要管理员权限")
return func(user, *args, **kwargs)
return wrapper
class User:
def __init__(self, name, is_admin):
self.name = name
self.is_admin = is_admin
@require_admin
def delete_database(user):
print(f"{user.name} 删除了数据库!")
admin = User("Alice", True)
hacker = User("Bob", False)
delete_database(admin) # 正常执行
delete_database(hacker) # 抛出 PermissionError
3. 自动重试机制
网络请求失败时自动重试
import random
from functools import wraps
def retry(max_attempts=3):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts+1):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"第 {attempt} 次尝试失败: {e}")
if attempt == max_attempts:
raise
return None
return wrapper
return decorator
@retry(max_attempts=2)
def unstable_api_call():
if random.random() < 0.8: # 模拟80%失败率
raise ConnectionError("API不可用")
return "数据获取成功"
print(unstable_api_call()) # 最多尝试两次
4. 路由注册
Web框架中的路由系统(类似Flask)
class Flask:
def __init__(self):
self.routes = {}
def route(self, path):
def decorator(func):
self.routes[path] = func
return func
return decorator
app = Flask()
@app.route("/")
def home():
return "首页内容"
@app.route("/about")
def about():
return "关于我们"
print(app.routes) # 输出: {'/': <function home...>, '/about': <function about...>}
5. 缓存加速
缓存计算结果避免重复运算(类似@lru_cache)
from functools import wraps
def simple_cache(func):
cache = {}
@wraps(func)
def wrapper(n):
if n not in cache:
print(f"计算 {n} 的阶乘...")
cache[n] = func(n)
return cache[n]
return wrapper
@simple_cache
def factorial(n):
return 1 if n <= 1 else n * factorial(n-1)
print(factorial(5)) # 第一次计算
print(factorial(5)) # 直接从缓存读取
6. 日志记录
记录函数调用信息
from functools import wraps
def log_calls(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"调用 {func.__name__},参数:{args} {kwargs}")
return func(*args, **kwargs)
return wrapper
@log_calls
def process_data(data, reverse=False):
return sorted(data, reverse=reverse)
process_data([3,1,2], reverse=True)
# 输出:调用 process_data,参数:([3, 1, 2],) {'reverse': True}
7. 类型检查
验证函数参数类型
from functools import wraps
def validate_types(*types):
def decorator(func):
@wraps(func)
def wrapper(*args):
for arg, type_ in zip(args, types):
if not isinstance(arg, type_):
raise TypeError(f"参数 {arg} 应为 {type_}")
return func(*args)
return wrapper
return decorator
@validate_types(int, int)
def add(a, b):
return a + b
print(add(2, 3)) # 正常
print(add("2", 3)) # 抛出 TypeError
设计思想总结
装饰器的核心价值在于:将通用功能(日志/权限/缓存等)与业务逻辑解耦。
当你发现多个函数需要相同的辅助功能时,就是使用装饰器的最佳时机。
实际开发中常见的装饰器应用场景还包括:
- 数据库事务管理
- 请求频率限制
- 输入数据验证
- 用户身份认证
- 单元测试的上下文管理

浙公网安备 33010602011771号