当前位置: 首页 > article >正文

从‘能用’到‘优雅’:Python函数设计的3个坏味道与5个重构技巧(附代码对比)

从‘能用’到‘优雅’Python函数设计的3个坏味道与5个重构技巧附代码对比在Python开发中函数是最基本的代码组织单元。许多开发者能够快速实现功能却往往忽视了函数设计的质量。本文将揭示三种典型的函数设计坏味道并通过五条重构技巧帮助你从能用的代码升级到优雅的代码。1. 识别函数设计的三大坏味道1.1 功能臃肿一个函数做太多事初学者常犯的错误是将多个不相关的功能塞进一个函数。例如def process_data_and_generate_report(data): # 数据清洗 cleaned [] for item in data: if item[value] 0: cleaned.append(item) # 数据分析 total sum(item[value] for item in cleaned) average total / len(cleaned) # 生成报告 report fTotal: {total}, Average: {average} with open(report.txt, w) as f: f.write(report) return report这个函数同时完成了数据清洗、分析和报告生成三个独立功能违反了单一职责原则。1.2 参数失控过长或复杂的参数列表当函数需要太多参数时往往意味着它承担了过多责任def create_user(first_name, last_name, email, phone, address, city, state, zip_code, country, is_adminFalse, is_activeTrue, registration_dateNone): # ...复杂的用户创建逻辑...超过5个参数的函数通常难以理解和维护且调用时容易出错。1.3 副作用泛滥不明确的输入输出不良函数设计常表现为修改全局变量改变输入参数的状态返回类型不一致有时返回None有时返回对象results [] def analyze_data(data): global results if not data: return None results [d*2 for d in data] return len(results)这个函数同时修改了全局变量和返回计算结果调用者难以预测其行为。2. 五条重构技巧提升函数质量2.1 单一职责原则拆分臃肿函数将前述process_data_and_generate_report拆分为三个专注单一功能的函数def clean_data(data): return [item for item in data if item[value] 0] def analyze_data(data): total sum(item[value] for item in data) return total, total / len(data) def generate_report(total, average): report fTotal: {total}, Average: {average} with open(report.txt, w) as f: f.write(report) return report重构后的代码每个函数只做一件事更容易测试和维护可以单独复用每个功能2.2 参数优化简化接口设计对于参数过多的函数可以考虑以下策略使用对象封装相关参数class UserInfo: def __init__(self, first_name, last_name, email, phoneNone, addressNone): self.first_name first_name self.last_name last_name self.email email self.phone phone self.address address def create_user(user_info, is_adminFalse, is_activeTrue): # 使用user_info对象而非多个参数使用默认参数和关键字参数def connect_to_db(host, port5432, userNone, passwordNone, timeout10, sslTrue): # 合理的默认值减少必须参数2.3 明确输入输出使用类型注解Python 3.5的类型注解可以显著提高代码可读性from typing import List, Tuple, Optional def analyze_data(data: List[dict]) - Tuple[float, float]: 分析数据并返回总和与平均值 Args: data: 包含value键的字典列表 Returns: 包含(total, average)的元组 total sum(item[value] for item in data) return total, total / len(data)类型注解的好处明确函数期望的输入类型声明返回值的类型IDE可以基于注解提供更好的代码补全和检查2.4 返回值优化使用命名元组替代复杂返回值当函数需要返回多个相关值时使用命名元组比普通元组更清晰from collections import namedtuple AnalysisResult namedtuple(AnalysisResult, [total, average, count]) def analyze_data(data): total sum(item[value] for item in data) return AnalysisResult(total, total/len(data), len(data)) result analyze_data(data) print(fAverage: {result.average}) # 比result[1]更清晰2.5 函数组合构建可复用的功能单元将小函数组合成更复杂的功能而不是创建大函数def pipeline(data): cleaned clean_data(data) analyzed analyze_data(cleaned) return generate_report(*analyzed)这种风格的优势每个小函数易于测试可以灵活重组功能代码更易于理解和维护3. 实战案例重构用户注册流程原始实现def register_user(username, password, email, first_name, last_name, addressNone, phoneNone, is_adminFalse): # 验证输入 if not all([username, password, email]): return False # 检查用户名是否已存在 if username in existing_users: return False # 密码强度检查 if len(password) 8: return False # 创建用户记录 user { username: username, password: hash_password(password), email: email, first_name: first_name, last_name: last_name, address: address, phone: phone, is_admin: is_admin } # 保存到数据库 db.save(user) # 发送欢迎邮件 send_email(email, Welcome, Thank you for registering!) return True重构后的版本def validate_input(username, password, email) - bool: return all([username, password, email]) def is_username_available(username) - bool: return username not in existing_users def is_password_strong(password) - bool: return len(password) 8 def create_user_record(username, password, email, **kwargs): return { username: username, password: hash_password(password), email: email, **kwargs } def register_user(username, password, email, **kwargs): if not (validate_input(username, password, email) and is_username_available(username) and is_password_strong(password)): return False user create_user_record(username, password, email, **kwargs) db.save(user) send_welcome_email(email) return True重构后的改进每个子功能独立且可测试主函数逻辑清晰更容易扩展和修改单个功能参数处理更灵活4. 高级技巧利用装饰器提升函数能力Python装饰器可以非侵入式地增强函数功能日志装饰器示例def log_function_call(func): def wrapper(*args, **kwargs): print(fCalling {func.__name__} with args{args}, kwargs{kwargs}) result func(*args, **kwargs) print(f{func.__name__} returned {result}) return result return wrapper log_function_call def calculate(a, b, operationadd): if operation add: return a b elif operation subtract: return a - b性能计时装饰器import time def timeit(func): def wrapper(*args, **kwargs): start time.perf_counter() result func(*args, **kwargs) elapsed time.perf_counter() - start print(f{func.__name__} took {elapsed:.6f} seconds) return result return wrapper装饰器的优势保持核心逻辑简洁可以灵活组合多个功能便于添加或移除横切关注点在实际项目中良好的函数设计能显著提高代码的可读性、可维护性和可测试性。从识别坏味道开始逐步应用这些重构技巧你的Python代码将变得更加优雅和专业。

相关文章:

从‘能用’到‘优雅’:Python函数设计的3个坏味道与5个重构技巧(附代码对比)

从‘能用’到‘优雅’:Python函数设计的3个坏味道与5个重构技巧(附代码对比) 在Python开发中,函数是最基本的代码组织单元。许多开发者能够快速实现功能,却往往忽视了函数设计的质量。本文将揭示三种典型的函数设计&qu…...

Tarjan算法:从DFS序到强连通分量的寻路指南(附C++实战与缩点技巧)

1. 从迷宫探索到强连通王国:Tarjan算法的生活隐喻 想象你正在探索一座巨大的迷宫,手里拿着粉笔和记事本。每走到一个新的岔路口,你就在墙上标记数字(第一个到的路口标1,第二个标2...),这就是DFS…...

Corvus Robotics推出可在零下仓库中自主盘点库存的新型无人机

物理AI机器人系统提供商Corvus Robotics近日发布了Corvus One冷链版——一款专为在零下20华氏度至常温环境下持续运行而设计的自主库存管理系统。该系统专为抵御极端低温、气流、霜冻和冷凝水而打造,能够在无需人工干预的情况下,对库存进行高频次、高精度…...

双强联袂,数智共舞 | 中聚信 × 金蝶启联巅峰对话,共探财税未来新航道

3 月 26 日,由金蝶软件(中国)有限公司、贵州启联科技有限公司联合主办,中聚信财税技术研究中心协办的「AI 时代 先进管理用金蝶」主题峰会,在贵阳国际生态会议中心圆满落幕。这场聚焦制造企业数字化转型与 AI 赋能管理…...

什么是dapr?为什么要使用它

官方文档https://docs.dapr.io/zh-hans/developing-applications/building-blocks/ 介绍 dapr是一个分布式运行时(Distributed Application Runtime)是一个开源项目,它把构建微服务的最佳实践沉淀为开发者可直接调用的标准化API,…...

ncmdump工具完全攻略:解锁网易云音乐NCM格式转换的终极指南

ncmdump工具完全攻略:解锁网易云音乐NCM格式转换的终极指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM加密格式无法在其他播放器播放而烦恼吗?你是否经历过精心收藏的音乐只能…...

【文件上传绕过】十六—十八:巧用文件幻数与内容伪装突破类型校验

1. 文件幻数:藏在二进制里的身份证 每次上传图片时,你有没有好奇过系统是怎么判断"这张图真的是JPG"的?这就像超市扫码器识别商品条形码一样,计算机其实是通过读取文件开头的几个特殊字节——我们称之为**幻数&#xff…...

从“鸡尾酒会”到手机通话:用生活场景图解CDMA码分多址到底是怎么“听清”你的

鸡尾酒会里的通信密码:用生活场景拆解CDMA如何从噪音中识别你的声音 1. 当鸡尾酒会遇见通信技术 想象你站在一个嘈杂的鸡尾酒会现场,四周充斥着数十人同时进行的对话。神奇的是,尽管声波在空气中混杂叠加,你的大脑却能自动过滤无关…...

LangGraph大模型脚手架实战:揭秘6种爆款智能体设计模式,玩转生产级Agent开发!

最近Herness大火,我就在反思,我们在日常进行智能体开发的过程中,是否也在做类似的事,我们用过claude code sdk、codex sdk、copilot cli等通用agent做封装,也用过dify或者coze搭工作流,也用过langchain做过…...

跨越平台壁垒:在STM32与MSP430上构建Arduino式开发体验

1. 为什么要在STM32和MSP430上实现Arduino开发体验? 我第一次接触嵌入式开发就是在Arduino平台上,那种插上USB就能烧录、几行代码让LED闪烁的爽快感,让我这个非科班出身的小白瞬间爱上了硬件编程。但后来参加电子设计竞赛时,队友递…...

AAAI‘2026 模型记错了,检索也救不了?KG+TruthfulRAG想解决这个死结

背景介绍 近年来,大语言模型(LLM)在生成与理解任务上表现突出,但其内部“参数化知识”具有静态、滞后的特点: 面对时效性知识、专业知识、隐私知识等,模型可能缺乏覆盖;即便检索增强生成&#…...

工业意识:03 组态软件怎么选?WinCC、FactoryTalk、国产一篇讲透

03 组态软件怎么选?WinCC、FactoryTalk、国产一篇讲透 前面咱们把SCADA聊成“千里眼”,MES聊成“透明玻璃房”,现在终于到最爽的部分——画面组态!简单说,就是用鼠标拖拖拽拽,在电脑上搭出那些监控大屏:仪表盘、按钮、趋势图、报警灯、3D管道……全连上PLC变量,点一下…...

【LeetCode 手撕算法】(二分查找)搜索插入位置、搜索二维矩阵、查找数组相同的所有位置、搜索旋转排序数组、旋转升序数组的最小值

复杂度为O(log n)且有序用二分查找35-搜索插入位置思路&#xff1a;二分查找&#xff0c;左右指针 求中间值注意&#xff1a;while的查询条件是>class Solution {public int searchInsert(int[] nums, int target) {int left0;int rightnums.length-1;while(left<right){…...

STM32F407上电后第一行代码:手把手带你读懂启动文件startup_stm32f407xx.s

STM32F407启动文件深度解析&#xff1a;从复位到main()的底层之旅 当你第一次打开STM32的MDK工程时&#xff0c;那个神秘的.s文件是否曾让你望而却步&#xff1f;作为连接硬件与C语言世界的桥梁&#xff0c;启动文件&#xff08;startup_stm32f407xx.s&#xff09;完成了从芯片…...

设计师连夜删稿的真相:Onion Skin未启用导致版本错位!3分钟紧急修复+历史帧自动锚定脚本

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;设计师连夜删稿的真相&#xff1a;Onion Skin未启用导致版本错位&#xff01;3分钟紧急修复历史帧自动锚定脚本 当动画师在 Toon Boom Harmony 或 Adobe Animate 中反复导出“看似正确”的中间帧&#…...

SteamAutoCrack技术深度解析:架构设计与实现原理揭秘

SteamAutoCrack技术深度解析&#xff1a;架构设计与实现原理揭秘 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack SteamAutoCrack是一款基于.NET 10.0框架开发的Steam游戏自动破解工具&…...

自感痕迹论的思想史意义:一场发生学范式的四维跃迁

自感痕迹论的思想史意义&#xff1a;一场发生学范式的四维跃迁摘要在当代思想版图中&#xff0c;人文精神与科学技术正处于前所未有的割裂状态。一方面&#xff0c;现象学、后结构主义在解构了宏大叙事后&#xff0c;陷入相对主义与操作空转的泥淖&#xff1b;另一方面&#xf…...

ComfyUI-Impact-Pack完整安装指南:为什么你的V8版本功能不全?终极解决方案

ComfyUI-Impact-Pack完整安装指南&#xff1a;为什么你的V8版本功能不全&#xff1f;终极解决方案 【免费下载链接】ComfyUI-Impact-Pack Custom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, …...

GD32F303硬件I2C实战:手把手教你用AT24C02 EEPROM存储和读取设备配置参数

GD32F303硬件I2C实战&#xff1a;构建工业级参数存储系统 在嵌入式设备开发中&#xff0c;系统参数的持久化存储是个看似简单却暗藏玄机的需求。想象一下&#xff0c;当你的智能温控器经历突然断电后&#xff0c;所有用户设置的日程和偏好全部归零——这种体验足以让产品口碑崩…...

在vSphere ESXi 7.0上跑MacOS Big Sur?这份保姆级避坑指南帮你一次搞定

在vSphere ESXi 7.0上部署macOS Big Sur的深度避坑指南 虚拟化环境中运行macOS一直是技术爱好者和企业开发者的热门需求。本文将深入探讨在vSphere ESXi 7.0平台上安装macOS Big Sur时可能遇到的各种技术难题及其解决方案&#xff0c;帮助您避开那些让大多数用户头疼的"坑…...

Spring Boot项目整合阿里云OSS上传,如何避免Nginx代理下的405坑?

Spring Boot整合阿里云OSS上传的Nginx避坑指南&#xff1a;彻底解决405错误 在前后端分离架构中&#xff0c;文件上传功能几乎是每个Web应用的标配。当我们将Spring Boot与阿里云OSS结合使用时&#xff0c;Nginx作为反向代理常常会带来一个棘手的405 Method Not Allowed错误。这…...

别再只用VGG19做分类了!手把手教你用PyTorch提取4096维图像特征向量(实战教程)

突破分类局限&#xff1a;用PyTorch解锁VGG19的深度特征提取实战 当你第一次接触VGG19时&#xff0c;可能被它的ImageNet分类能力所震撼。但如果你只把它当作一个分类器&#xff0c;那就如同用瑞士军刀只开瓶盖——大材小用。在计算机视觉领域&#xff0c;预训练模型真正的价值…...

PyTorch模型参数管理:从torch.nn.Parameter到高效训练实践

1. 理解torch.nn.Parameter的本质 第一次接触PyTorch的torch.nn.Parameter时&#xff0c;我也曾困惑它和普通Tensor的区别。直到在实际项目中踩了几个坑&#xff0c;才真正明白它的价值。让我们从一个简单的例子开始&#xff1a; import torch import torch.nn as nn# 普通Te…...

MATLAB 2018a/2023b实测:Libsvm安装后如何用自带数据集快速验证与跑通第一个模型

MATLAB 2018a/2023b实战&#xff1a;Libsvm安装后快速验证与模型跑通全流程 当你第一次在MATLAB中成功安装Libsvm后&#xff0c;那种兴奋感可能很快会被"接下来该做什么"的迷茫所取代。别担心&#xff0c;这篇文章将带你用Libsvm自带的heart_scale数据集&#xff0c;…...

NoFences:彻底解决Windows桌面杂乱问题,免费开源桌面整理革命

NoFences&#xff1a;彻底解决Windows桌面杂乱问题&#xff0c;免费开源桌面整理革命 【免费下载链接】NoFences &#x1f6a7; Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 你是否厌倦了Windows桌面上满屏的图标&a…...

3步解锁联想刃7000k BIOS隐藏功能:安全提升硬件性能的完整指南

3步解锁联想刃7000k BIOS隐藏功能&#xff1a;安全提升硬件性能的完整指南 【免费下载链接】Lenovo-7000k-Unlock-BIOS Lenovo联想刃7000k2021-3060版解锁BIOS隐藏选项并提升为Admin权限 项目地址: https://gitcode.com/gh_mirrors/le/Lenovo-7000k-Unlock-BIOS 联想刃7…...

3步搭建你的英雄联盟智能助手:LeagueAkari完整操作指南

3步搭建你的英雄联盟智能助手&#xff1a;LeagueAkari完整操作指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power &#x1f680;. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 想象一下&#xff0c;当你正…...

NVIDIA显卡终极调校指南:用Profile Inspector释放游戏潜能的简单方法

NVIDIA显卡终极调校指南&#xff1a;用Profile Inspector释放游戏潜能的简单方法 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 还在为游戏卡顿、画面撕裂而烦恼吗&#xff1f;NVIDIA Profile Inspect…...

英雄联盟专业视频编辑器:用League Director制作电影级游戏录像的完整指南

英雄联盟专业视频编辑器&#xff1a;用League Director制作电影级游戏录像的完整指南 【免费下载链接】leaguedirector League Director is a tool for staging and recording videos from League of Legends replays 项目地址: https://gitcode.com/gh_mirrors/le/leaguedir…...

视频字幕提取神器:如何让AI帮你自动转录硬字幕?

视频字幕提取神器&#xff1a;如何让AI帮你自动转录硬字幕&#xff1f; 【免费下载链接】video-subtitle-extractor 视频硬字幕提取&#xff0c;生成srt文件。无需申请第三方API&#xff0c;本地实现文本识别。基于深度学习的视频字幕提取框架&#xff0c;包含字幕区域检测、字…...