提升Python代码质量的技巧

在这篇文章中,将探讨一些实用的编程技巧,旨在帮助数据科学家和Python爱好者编写更优质、更清晰的代码。这些技巧不仅个人在日常生活中使用,而且它们极大地提升了编程风格。因此,希望能够与大家分享这些技巧,以便每个人都能从中学习。将学到如何编写易于扩展且易于维护的高质量Python脚本。

虽然循环遍历一个小列表可能不是什么大问题,但想象一下,当需要遍历一个大型数据集时,将无法知道代码是否已经完成,这是不公平的,对吧?因此,为了消除是否处于无限循环或仅仅是耗时任务的疑虑,请使用tqdm库来显示进度条。

from tqdm import tqdm for i in tqdm(range(100000000), desc="遍历循环"):   pass

上述代码将生成一个进度条,并显示循环执行情况以及其他详细信息,例如每秒迭代速度和完成循环所需的总时间。"DESC"参数允许传递一个合适的描述来显示循环。

类型提示意味着明确声明Python函数的所有参数。这些在日常工作中非常有用,几乎总是使用它们。知道吗?可以在Python函数定义中指定返回类型。虽然不经常使用它,但它存在,并且可以被认为是一个好的编码标准。以下代码演示了这一点:

from pandas import DataFrame from typing import List def update_df(df: DataFrame, classifier: str, accuracy: float, split_size: float = 0.5, remarks: List[str] = []) -> DataFrame:   new_row = {'Classifier': classifier, 'Accuracy': accuracy, 'split_size': split_size, 'Remarks': remarks}   df = df.append(new_row, ignore_index=True)   return df df = DataFrame(columns=["Classifier", "Accuracy", "split_size", "Remarks"]) df = update_df(df, "KNN", 88, 0.1) df = update_df(df, "SVM", 90, remarks=["再次检查"]) df = update_df(df, "LR", 80, 0.8, remarks=["参数调整", "过拟合"]) df

上述函数返回一个数据框,可以在现有的数据框中追加新行。这里的代码可能看起来有点奇怪,但应该考虑以下几点关于上述代码:

"->"符号在函数定义后定义了函数将返回的值类型。在这种情况下,函数返回一个pandas数据框。这也被称为其他编程语言中的返回类型。

任何函数的默认值都可以以"参数:类型 = 值"的格式定义,例如在上述函数中,"split: float = 0.5"为split变量设置了默认值0.5,数据类型为浮点数。

Python中默认的函数返回类型与其他语言中的"void"不同,是"None"。

如果想要有混合类型的返回,例如,根据工作,一个函数可以打印一些东西或返回一个值。该函数也可以是整数或浮点数值。在这种情况下,可以使用Python的"Union"功能,如下所示:

# 对于所有Python版本都有效,从Python 3.10开始弃用 from typing import Union def func(val: int = 0) -> Union[None, int]:   pass # 在Python 3.10及以上版本,不需要union关键字,可以直接使用“或”操作符。示例: def func(val: int = 0) -> None | int:   pass

可以在函数定义中尽可能具体地进行类型提示。例如,在例子中,对于“Remarks”,指定它将是一个列表,列表将是“str”或字符串格式。这里应该记住一件事,Python不提供内置的类型错误检查类型提示,传递一个整数列表不会产生错误。至少在3.10及以下版本中目前是这样。因此,需要编写手动错误检查代码。

可以想象一个场景,用户可以传递一个未公开或不确定数量的参数,或者想要输入目录路径,这些路径可以通过用户输入是1个或50个不同的路径。显然,编写“def func(para1, para2…)”可能不是最佳行动方案,在这种情况下,可以使用“args”和“kwargs”。应该记住这两个关键字的目的。

Args用于指定未知数量的位置参数。

Kwargs用于指定未知数量的关键字参数。

import os def count_files_in_dir(project_root_dir, *fpaths: str):   for path in fpaths:     rel_path = os.path.join(project_root_dir, path)     print(path, ":", len(os.listdir(rel_path))) count_files_in_dir("../usr", "games", "include", "local", "bin")

注意:这里在计算Google Collab目录中的文件数量。

在函数调用中,实际上传递了5个参数,函数定义期望一个强制性的位置参数,其余的都被“*fpaths”吸收,然后可以计算文件数量。吸收的技术术语实际上是“参数打包”。

经常编写的代码可能缺乏适当的格式化或有时会变得混乱。尾随空格、额外的逗号、未排序的导入语句以及缩进中的空间等都可能是一个麻烦的问题。当然可以手动解决所有这些问题,但如果使用pre-commit钩子,可以节省大量时间。

这些钩子可以使用一行代码“pre-commit run”进行自动格式化。

需要创建自己的“pre-commit-config.yaml”文件,其中包含所有想要遵循的格式化规则的信息。在执行pre-commit run之前,应该使用git add将文件分阶段,否则所有文件都将被跳过。

几乎使用VS-Code处理所有事情,它非常有帮助,但有了这些扩展,可以提高生产力,个人认为这些扩展非常有用。它们如下:

  • Bracket Pair Colorizer - 将匹配的括号配对成相同的颜色
  • Path Intellisense - 允许自动完成文件名
  • PythonDocstring Generator - 允许为Python生成文档字符串
  • Python Indent - 允许代码在多行运行时正确缩进
  • Python Type Hint - 允许在编写函数时自动完成类型提示
  • TODO Tree - 将所有TODO集中在一起,这些TODO作为注释并包含TODO这个词
  • Pylance - 有助于代码补全和参数建议
def func():   '''这是一个文档字符串的示例函数'''   pass func.__doc__
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485