Python 权限装饰器与日志模块:给函数穿防护马甲 + 让程序写日记

发布时间:2026/7/31 5:49:59

Python 权限装饰器与日志模块:给函数穿防护马甲 + 让程序写日记 文章目录 前言第一部分权限装饰器 —— 给函数“穿防护马甲”1.1 权限装饰器 —— 未登录有效保护1.2 怎么调用装饰器1.3 wraps(func) 是干嘛的1.4 装饰器核心总结第二部分logging 日志模块 —— 让程序学会“写日记”2.1 为什么要用日志2.2 日志的五个级别从低到高2.3 基础用法 —— 按你图中的代码来2.4 图解日志是怎么流动的2.5 多个日志实例独立模块2.6 日志格式占位符说明2.7 日志模块核心总结 结尾 前言在 Python 编程中我们常常会遇到一些看似简单却非常实用的技巧它们能极大提升代码的可维护性和安全性。今天不讲复杂的概念就聊两件特别实用的事第一件权限装饰器—— 这是一种优雅的设计模式它允许你在不改变函数本身代码的情况下为函数“穿上防护马甲”添加额外的功能。想象一下你有一个需要登录才能访问的个人中心页面传统做法是在每个函数开头都加上登录检查的代码这样不仅重复还容易出错。而装饰器可以让你用一行login_required就搞定所有需要权限验证的函数代码简洁又安全。第二件日志模块—— 这是程序“写日记”的能力。在开发阶段我们习惯用print()来调试但当程序部署到服务器上后你不可能一直盯着屏幕看输出。日志模块让程序能够自动把运行过程中的关键信息如错误、警告、用户操作等记录到文件中。当程序出现问题时你可以像查案一样翻阅日志文件快速定位问题根源这比靠眼睛盯着屏幕找错误靠谱一万倍。这两件事虽然基础但却是 Python 开发中不可或缺的实用技能。本文将按照清晰的思路分开讲解这两个主题每个部分都配有详细的代码示例和流程图确保你不仅能理解原理还能立即上手应用到自己的项目中。让我们开始吧第一部分权限装饰器 —— 给函数“穿防护马甲”1.1 权限装饰器 —— 未登录有效保护pythonfrom functools import wraps user None # 全局变量记录当前登录用户默认没人 def login_required(func): wraps(func) # 保留原函数的名字和注释方便调试 def check_login(): check_login 注释说明 global user if user: # 已经登录了 → 直接执行原函数 func() else: # 没登录 → 让用户输入账号密码 user_name input(输入用户名) password input(输入密码) if user_name admin and password 123456: user user_name func() else: print(用户名或者密码错误) return check_login这段代码的执行逻辑text调用被装饰的函数 ↓ 检查 user 是否为空 ↓ ┌────┴────┐ ↓ ↓ user 有值 user 是 None 已登录 未登录 ↓ ↓ 直接执行 让你输账号密码 原函数 ↓ ┌───┴───┐ ↓ ↓ 正确 错误 ↓ ↓ 登录成功 提示错误 ↓ 执行原函数1.2 怎么调用装饰器python# 普通函数不用登录就能看 def index(): print(欢迎来到首页) 加了 login_required 的函数必须先登录才能进 login_required def center(): center 是个人中心 print(欢迎来到个人中心) login_required def wallet(): print(欢迎来到钱包页面) 调用 index() # 直接输出欢迎来到首页 center() # 没登录的话会让你输账号密码 wallet() # 登录过一次之后后面的函数直接放行运行效果第一次调用center()text输入用户名admin 输入密码123456 欢迎来到个人中心第二次调用wallet()已登录不用再输text欢迎来到钱包页面1.3wraps(func)是干嘛的不加wraps(func)你的函数名字会被“偷换”掉python# 不加 wraps def login_required(func): def check_login(): pass return check_login login_required def center(): 我是个人中心 pass print(center.name) # check_login ← 函数名变了加了wraps(func)之后pythonfrom functools import wraps def login_required(func): wraps(func) def check_login(): pass return check_login login_required def center(): 我是个人中心 pass print(center.name) # center ← 还是原来的名字 一句话wraps的作用就是“把原函数的身份信息名字、注释等复制给包装函数”方便调试和查错。1.4 装饰器核心总结概念说明本质闭包 语法糖作用不改变原函数给函数加新功能wraps保住原函数的名字和注释global user在函数里修改全局变量login_required执行函数前先校验是否登录第二部分logging日志模块 —— 让程序学会“写日记”2.1 为什么要用日志写代码的时候你习惯用print()来调试。但程序跑在服务器上之后你不可能一直盯着屏幕看。这时候就需要日志——程序自己把运行信息写进文件里出问题了你去翻文件就能查到。日志的作用场景说明排查错误程序崩了翻日志看哪里出了问题监控运行看程序在什么时间干了什么事记录关键操作谁在什么时候删了什么数据2.2 日志的五个级别从低到高级别函数啥时候用DEBUGlogger.debug()调试信息最详细INFOlogger.info()常规运行信息WARNINGlogger.warning()警告不影响运行ERRORlogger.error()出错了但程序还能跑CRITICALlogger.critical()严重错误程序要挂了级别规则设置了setLevel(logging.WARNING)就只会记录WARNING及以上级别WARNING、ERROR、CRITICALDEBUG和INFO就不显示了。2.3 基础用法 —— 按你图中的代码来pythonimport logging 1. 创建日志实例 logger logging.getLogger(name) # name 是当前模块名 logger.setLevel(logging.DEBUG) # 设置级别覆盖默认的 WARNING 2. 创建控制台处理器输出到屏幕 stream_handler logging.StreamHandler() stream_handler.setLevel(logging.INFO) # 控制台只显示 INFO 及以上 设置控制台输出格式 stream_formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) stream_handler.setFormatter(stream_formatter) 把处理器添加到日志实例 logger.addHandler(stream_handler) 3. 创建文件处理器输出到文件 file_handler logging.FileHandler(log.txt) file_handler.setLevel(logging.WARNING) # 文件只记录 WARNING 及以上 设置文件输出格式 file_formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) file_handler.setFormatter(file_formatter) 把处理器添加到日志实例 logger.addHandler(file_handler) 4. 输出日志 logger.debug(debug 信息) # 只有控制台显示因为控制台是 INFO会显示 DEBUG 及以上 logger.info(info 信息) # 控制台显示INFO 及以上文件不显示WARNING 以下不记录 logger.warning(warning 信息) # 控制台 文件都显示 logger.error(error 信息) # 控制台 文件都显示 logger.critical(critical 信息)# 控制台 文件都显示2.4 图解日志是怎么流动的textlogger.setLevel(DEBUG) ↓ 日志实例总开关DEBUG ↓ ┌────┴────┐ ↓ ↓ 控制台处理器 文件处理器 setLevel(INFO) setLevel(WARNING) ↓ ↓ 显示 INFO及以上 显示 WARNING及以上 ↓ ↓ 屏幕 log.txt一句话总开关决定哪些日志能进系统各个处理器再根据自己的级别决定哪些显示到屏幕、哪些写到文件。2.5 多个日志实例独立模块不同模块可以用各自的日志实例互不干扰python# 在另一个文件或另一个模块里 logger2 logging.getLogger(用户模块) logger2.setLevel(logging.DEBUG) file_handler logging.FileHandler(log2.txt, encodingutf-8) file_handler.setLevel(logging.WARNING) file_formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) file_handler.setFormatter(file_formatter) logger2.addHandler(file_handler) logger2.info(用户登录了) # 只显示在屏幕 logger2.warning(用户多次输错密码) # 显示在屏幕 写入 log2.txtlogging.getLogger(用户模块)里的名字会出现在日志中方便你区分是哪块代码打的日志。2.6 日志格式占位符说明占位符含义示例%(asctime)s时间2026-07-30 14:30:25%(name)s日志实例名称__main__或用户模块%(levelname)s日志级别INFO、WARNING%(message)s日志内容你写的具体信息%(filename)s文件名demo.py%(lineno)d行号102.7 日志模块核心总结组件作用getLogger(name)创建日志实例setLevel()设置总级别StreamHandler()输出到控制台屏幕FileHandler()输出到文件Formatter()设置日志格式logger.debug/info/warning/error/critical()输出不同级别的日志 今天知识点速查装饰器部分概念说明login_required加登录校验装饰器wraps(func)保住原函数名字global user修改全局变量本质闭包 语法糖日志部分级别函数用途DEBUGlogger.debug()调试信息INFOlogger.info()常规信息WARNINGlogger.warning()警告ERRORlogger.error()错误CRITICALlogger.critical()严重错误 结尾今天两件事都不难但特别实用权限装饰器能为你的网页在未登录时提供有效保护避免非法访问和攻击。日志模块让你程序学会写日记出了错翻文件查不用靠print()一条条盯着屏幕看。两个工具让你的码农之路又获得一些技能吧各位糕手下期我们聊点啥呢保持期待吧 咱们下期见

相关新闻