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

当函数返回有多个返回值时,需要注意的问题 : Effective Python 第19条

在Python编程中,函数返回多个值是一个常见需求。Python的拆包机制为这一需求提供了简洁而强大的解决方案。然而,当返回的值较多时,简单的拆包可能导致代码难以维护和理解。本文将探讨如何有效地管理函数返回的多个值,确保代码的可读性和可维护性。

一、函数返回多个值的常见方法

1. 使用元组返回多个值

Python允许函数返回一个元组,从而实现返回多个值的功能。元组中的每个元素对应一个返回值。例如:

def get_stats(numbers):minimum = min(numbers)maximum = max(numbers)return minimum, maximumlengths = [63, 73, 72, 60, 67, 66, 71, 61, 72, 70]
minimum, maximum = get_stats(lengths)
print(f'Min: {minimum}, Max: {maximum}')

在这个例子中,get_stats函数返回一个包含最小值和最大值的元组。调用函数时,通过拆包机制将元组中的值分配给minimummaximum变量。

2. 拆包机制的应用

拆包机制不仅适用于函数返回值的接收,还可以在其他场景中使用。例如:

first, second = 1, 2
assert first == 1
assert second == 2def my_function():return 1, 2first, second = my_function()
assert first == 1
assert second == 2

通过拆包机制,可以方便地将元组中的值分配给多个变量,提高了代码的简洁性和可读性。

二、拆分过多变量的问题

当函数需要返回较多的值时,直接拆分到多个变量中可能会带来以下问题:

1. 顺序错误

多个数值返回时,容易搞错变量的顺序,导致逻辑错误。例如:

minimum, maximum, average, median, count = get_stats(lengths)

如果get_stats函数返回的顺序发生变化,而调用方没有相应调整变量的顺序,就会导致错误。

2. 代码冗长

拆分多个变量时,代码可能变得冗长,难以阅读和维护。例如:

minimum, maximum, average, median, count = get_stats(lengths)minimum, maximum, average, median, count = \get_stats(lengths)(minimum, maximum, average,median, count) = get_stats(lengths)(minimum, maximum, average, median, count) = get_stats(lengths)

这些代码都试图拆分多个变量,但由于行数过多或格式混乱,降低了代码的可读性。

三、解决方案:使用命名元组或类封装返回值

为了避免上述问题,可以采用以下方法:

1. 使用命名元组

命名元组是一种轻量级的数据结构,允许为每个元素指定名称,从而提高代码的可读性和维护性。

from collections import namedtupleStats = namedtuple('Stats', ['minimum', 'maximum', 'average', 'median', 'count'])def get_stats(numbers):minimum = min(numbers)maximum = max(numbers)count = len(numbers)average = sum(numbers) / countsorted_numbers = sorted(numbers)middle = count // 2if count % 2 == 0:lower = sorted_numbers[middle - 1]upper = sorted_numbers[middle]median = (lower + upper) / 2else:median = sorted_numbers[middle]return Stats(minimum, maximum, average, median, count)stats = get_stats(lengths)
print(f'Min: {stats.minimum}, Max: {stats.maximum}')
print(f'Average: {stats.average}, Median: {stats.median}, Count: {stats.count}')

通过命名元组,每个统计值都有一个明确的名称,避免了因顺序错误导致的问题,同时提高了代码的可读性。

2. 使用类封装

类是一种更强大的数据封装工具,可以提供更多的功能,如类型检查、方法定义等。

class Stats:def __init__(self, minimum, maximum, average, median, count):self.minimum = minimumself.maximum = maximumself.average = averageself.median = medianself.count = countdef get_stats(numbers):minimum = min(numbers)maximum = max(numbers)count = len(numbers)average = sum(numbers) / countsorted_numbers = sorted(numbers)middle = count // 2if count % 2 == 0:lower = sorted_numbers[middle - 1]upper = sorted_numbers[middle]median = (lower + upper) / 2else:median = sorted_numbers[middle]return Stats(minimum, maximum, average, median, count)stats = get_stats(lengths)
print(f'Min: {stats.minimum}, Max: {stats.maximum}')
print(f'Average: {stats.average}, Median: {stats.median}, Count: {stats.count}')

类封装不仅提供了明确的属性访问方式,还可以在类中添加方法,实现更复杂的功能,如统计值的验证或计算。

四、其他建议

  • 避免复杂的拆分:如果必须拆分多个变量,可以考虑使用带星号的变量来捕获剩余的值。例如:

    def get_avg_ratio(numbers):average = sum(numbers) / len(numbers)scaled = [x / average for x in numbers]scaled.sort(reverse=True)return scaledlongest, *middle, shortest = get_avg_ratio(lengths)print(f'Longest:  {longest:>4.0%}')
    print(f'Shortest: {shortest:>4.0%}')
    

    这里,*middle捕获了longestshortest之间的所有值,简化了代码的编写。

  • 保持代码简洁:遵循PEP8风格指南,避免过长的拆分代码行,可以使用折行或拆分表达式来提高可读性。

    minimum, maximum, average, median, count = get_stats(lengths
    )
    

    通过适当的代码格式,可以提高代码的可读性,使其更易于维护。

五、总结

在Python中,函数返回多个值是一个常见需求。通过元组和拆包机制,可以方便地实现这一功能。然而,当返回的值较多时,直接拆分到多个变量中可能会导致代码难以维护和理解。为了提高代码的可读性和可维护性,可以采用以下方法:

  1. 使用命名元组:为每个返回值指定明确的名称,避免顺序错误,提高代码的可读性。
  2. 使用类封装:通过类来封装返回值,提供更强大的数据管理和功能扩展能力。

通过合理选择和使用这些方法,可以确保代码的清晰和高效,减少潜在的错误和维护成本。

http://www.dtcms.com/a/320182.html

相关文章:

  • C++ vector 扩容时到底发生了什么?
  • 一个程序通过 HTTP 协议调用天气 API,解析 JSON 格式的天气数据,提取关键信息并格式化输出:日期、天气状况、温度范围、风向、湿度等核心气象数据。
  • 1688 商品详情接口开发实战:从平台特性到高可用实现
  • Redis最新安装教程(WindowsLinux)
  • 对基带信号进行调制的原因及通俗理解
  • HR人才测评工具,卡特尔16pf性格测试
  • Numpy科学计算与数据分析:Numpy数学函数入门与实践
  • 我爱发明之Linux下使用Conky在桌面显示Spotify状态及封面字符画
  • 无损音乐下载器!(电脑)绿色免费,无限下载,无损音质
  • 是否将标签页tag信息存储在Redux store中还是仅存储在hook的state中
  • AI题解5
  • 什么是0.5米分辨率卫星影像数据?
  • 一文学会c++继承 组合
  • [优选算法专题一双指针——两数之和](双指针和哈希表)
  • 解决GitHub push失败-Failed to connect to github.com port 443: Timed out
  • 亚马逊卖家反馈机制变革:纯星级评级时代的合规挑战与运营重构
  • SOMGAN:用自组织映射改善GAN的模式探索能力
  • 自然语言处理×第四卷:文本特征与数据——她开始准备:每一次输入,都是为了更像你地说话
  • python selenium环境安装
  • Python自动化测试selenium指定截图文件名方法
  • MySQL 备份利器 Xtrabackup 全解析:从部署到恢复的实战指南
  • 视觉语言模型的空间推理缺陷——AI 在医学扫描中难以区分左右
  • 《CogAgent: A Visual Language Model for GUI Agents》论文精读笔记
  • Vue 3 入门教程 9 - 表单处理
  • 8、Redis的HyperLogLog、事务Multi、管道Pipeline,以及Redis7.0特性
  • DoubleTrouble靶机
  • 【R语言】重新绘制高清MaxEnt的单因素响应曲线图像
  • 最佳左前缀法则(Optimal Left-Prefix Rule)
  • 【Dijkstra】 Shortest Routes I
  • 5种将Android联系人传输到电脑的方法