首页 > 编程语言 >PEP 8 – Python 代码风格指南中文版(六)

PEP 8 – Python 代码风格指南中文版(六)

时间:2024-08-09 23:26:03浏览次数:14  
标签:__ None 函数 Python 中文版 PEP 表达式 lambda

编程建议(1)

  • 我们应该以一种不会对其他Python实现(比如PyPy、Jython、IronPython、Cython、Psyco等)造成不利影响的方式来编写。

例如,不要依赖CPython中对于a += b或a = a + b形式的语句在原地字符串连接上的高效实现。这种优化即使在CPython中也是脆弱的(它仅对某些类型有效),并且在不使用引用计数的实现中根本不存在。在库的性能敏感部分,应使用''.join()形式来确保跨各种实现的连接操作是线性的。

解释:

这里的其他Python实现指的是除了CPython(最广泛使用的Python解释器)之外的其他Python解释器或编译器。每个实现都有其独特的特点和优势,比如PyPy专注于提高Python代码的执行速度,Jython可以让Python代码在Java虚拟机上运行,IronPython可以让Python代码在.NET框架上运行等。

换句话说,我们应该让我们的代码尽可能具有可移植性和兼容性,以便它可以在不同的Python解释器或编译器上运行,而不会出现性能下降、功能缺失或其他问题。

  • 当你需要比较一个变量是否等于None这样的单例时,应该总是使用isis not操作符,而不是使用等号(==)或不等号(!=)这样的相等性操作符。

另外,当你实际上想要表达if x is not None时,要小心不要直接写if x——比如,在测试一个默认为None的变量或参数是否被设置为其他值时。那个“其他值”可能有一个在布尔上下文中会被视为False的类型(比如一个容器)!

解释:

在Python中,None是一个特殊的单例对象,意味着整个程序中只有一个None。因此,当你想要检查一个变量是否确实指向了None(而不是仅仅值上相等),你应该使用isis not来比较。这是因为is操作符比较的是两个对象的身份(即它们是否是同一个对象),而==操作符比较的是两个对象的值。虽然对于None这样的单例来说,使用==is在结果上可能是相同的,但使用is是更加准确和推荐的方式。

在Python中,if语句后面的表达式会被隐式地转换成布尔值。很多值在布尔上下文中都会被视为False,除了True、任何非零数值、非空字符串、非空容器(如列表、字典、集合等)以及非None的对象。因此,如果你只是简单地写if x来检查一个变量x是否“为真”,那么当x是一个空容器或其他在布尔上下文中被视为False的值时,这个检查就会失败。而如果你实际上想要检查的是x是否不是None,那么你应该明确地写if x is not None。这样,无论x是什么类型的值,只要它不是None,这个条件就会为真。

  • 使用is not操作符而不是not ... is。虽然这两个表达式在功能上是相同的,但前者更易于阅读,是首选的写法。

# 正确的:
if foo is not None:

# 错误的:
if not foo is None:

 解释:

在Python中,当你想要检查一个对象是否不是某个特定的单例(比如None)时,你有两种方式来写这个逻辑:

  1. 使用not ... is的方式,比如not x is None
  2. 使用is not的方式,即x is not None

虽然从逻辑上讲,这两种写法都是正确的,并且它们会得到相同的结果,但是PEP-8建议我们使用第二种方式(is not),因为它更加直观和易于阅读。

原因在于,当我们按照英语的阅读习惯从左到右扫描代码时,x is not None更符合我们的思维习惯。它首先识别出x,然后紧接着是一个清晰的否定判断is not,最后是一个明确的比较对象None。这种结构让我们能够快速地理解代码的含义,而不需要在脑海中重新组织语句的顺序。

相比之下,not x is None虽然逻辑上也是正确的,但它需要我们先处理x is None这个子表达式,然后再对结果取反。这种额外的处理步骤可能会让代码的阅读者稍微感到困惑,尤其是在更复杂的表达式中。

因此,遵循PEP-8的建议,我们应该优先使用is not来编写这样的逻辑表达式。

  • 在实现带有丰富比较功能的排序操作时,最好实现所有六个比较操作(__eq__, __ne__, __lt__, __le__, __gt__, __ge__),而不是依赖其他代码仅执行特定的比较。

为了最小化所需的工作量,functools.total_ordering() 装饰器提供了一个工具来生成缺失的比较方法。

PEP 207 指出 Python 假定反身性规则。因此,解释器可能会将 y > x 替换为 x < y,将 y >= x 替换为 x <= y,并可能交换 x == y 和 x != y 的参数。sort() 和 min() 操作保证使用 < 操作符,而 max() 函数使用 > 操作符。然而,最好实现所有六个操作,以避免在其他上下文中产生混淆。

解释:

在Python中,如果你想让你的对象支持排序和比较操作,那么最好实现所有六种比较方法(相等、不等、小于、小于等于、大于、大于等于)。不要只实现其中一部分,然后期望其他代码来填补剩下的空白。

不过,为了让你不那么辛苦,Python的functools模块提供了一个total_ordering()装饰器。这个装饰器可以帮你自动生成缺失的比较方法,只要你实现了__eq__和至少一个“不严格”的比较方法(比如__lt____gt__),它就能利用这些方法来推断出其他缺失的比较方法。

Python有一个规则,叫做“反射性规则”,它允许解释器在比较操作中进行一些优化,比如交换比较运算符的两边。这意味着,即使你只实现了部分比较方法,Python也可能会在内部使用它们来进行其他类型的比较。但是,为了确保你的对象在所有情况下都能正确地进行比较,最好还是实现所有六种比较方法。特别是,当你使用sort()min()max()等函数时,虽然它们有明确的操作符偏好,但在其他自定义的上下文中,完整的比较实现将避免潜在的混淆和错误。

总之,当你想要让你的Python对象支持排序和比较时,遵循PEP-8的建议,实现所有六种比较方法是一个好习惯。虽然functools.total_ordering()装饰器可以帮你减轻一些负担,但理解这些比较方法如何工作以及为什么需要它们仍然是很重要的。

  • 始终使用 def 语句而不是将 lambda 表达式直接绑定到标识符的赋值语句:

这意味着,当你需要定义一个函数时,应该使用 def 关键字来明确声明它,而不是通过赋值语句将 lambda 表达式的结果(即一个函数对象)赋给一个变量名。这样做可以提高代码的可读性和可维护性。

# 正确的:
def f(x): return 2*x

# 错误的:
f = lambda x: 2*x

第一种形式意味着生成的函数对象的名称具体是 'f' 而不是通用的 '<lambda>'。这在回溯和一般的字符串表示中更为有用。使用赋值语句消除了 lambda 表达式相对于显式 def 语句所能提供的唯一好处(即它可以嵌入到更大的表达式中)。

解释:

在Python中,你可以使用两种方式来定义函数:一种是使用def关键字,后跟函数名和参数列表,以及函数体;另一种是使用lambda关键字来创建一个匿名函数(即没有名称的函数),并将其赋值给一个变量。然而,PEP-8建议尽量使用def语句来定义函数,因为它更加清晰和易于维护。

lambda 表达式用于创建匿名函数(即没有名称的函数)。然而,当你将 lambda 表达式的结果(即函数对象)赋值给一个变量时,虽然这个变量现在引用了这个函数对象,但函数对象本身仍然保持匿名(在内部表示中,它可能仍然显示为 '<lambda>')。相比之下,使用 def 语句定义的函数,你可以给函数指定一个有意义的名称,这个名称会在错误追踪、调试和文档等场合中使用。而lambda表达式创建的匿名函数在错误追踪中只会显示为<lambda>,这可能会让调试变得更加困难。此外,在字符串表示中,使用明确的函数名也更易于理解。。

虽然 lambda 表达式允许你将函数定义嵌入到更大的表达式中,但如果你只是将 lambda 表达式的结果赋值给一个变量(如 f = lambda x: x + 1),那么你就失去了 lambda 表达式的这一主要优势,因为此时你已经通过变量名 f 显式地引用了这个函数。在这种情况下,使用 def 语句会更清晰、更易于维护。

 相关文章:

PEP 8 – Python 代码风格指南中文版(一)

PEP 8 – Python 代码风格指南中文版(二)

PEP 8 – Python 代码风格指南中文版(三)

PEP 8 – Python 代码风格指南中文版(四)

PEP 8 – Python 代码风格指南中文版(五)

标签:__,None,函数,Python,中文版,PEP,表达式,lambda
From: https://blog.csdn.net/sosogod/article/details/140916941

相关文章

  • 【Python】Python中一些有趣的用法
    Python是一种非常灵活和强大的编程语言,它有很多有趣的用法,以下是一些例子:一行代码实现FizzBuzz:print('\n'.join(['FizzBuzz'[i%3*4:i%5*8:-1]orstr(i)foriinrange(1,101)]))使用列表推导式生成斐波那契数列:fib=[0,1][fib.append(fib[-2]+fib[-1])for_......
  • OpenCV与AI深度学习 | 手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤 +
    本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。原文链接:手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤+源码)导 读    本文将手把手教你用Python和OpenCV搭建一个半自动标注工具(包含详细步骤+源码)。背景介绍    样本标......
  • Python教程(十三):常用内置模块详解
    目录专栏列表1.`os`模块2.`sys`模块3.`re`模块4.`json`模块5.`datetime`模块6.`math`模块7.`random`模块8.`collections`模块9.`itertools`模块10.`threading`模块总结专栏列表Python教程(十):面向对象编程(OOP)Python教程(十一):单元测试与异常捕获Py......
  • Adobe Premiere Pro PR2024中文版win/mac软件安装下载
    一、简介AdobePremierePro2024(简称PR2024)是Adobe公司推出的一款专业视频编辑软件,广泛应用于电影、电视、网络视频制作等领域。作为AdobeCreativeSuite的一部分,PR2024继承了Adobe家族一贯的简洁界面和强大功能,同时结合了最新的技术和用户需求,为用户提供了更加高效、直观......
  • 2024年华为OD机试真题-求幸存数之和-(C++/Java/python)-OD统一考试(C卷D卷)
    2024华为OD机试真题目录-(B卷C卷D卷)-【C++JavaPython】_华为od机试csdn-CSDN博客 题目描述给一个正整数数列nums,一个跳数jump,及幸存数量left。运算过程为:从索引0的位置开始向后跳,中间跳过J个数字,命中索引为J+1的数字,该数被敲出,并从该点起跳,以此类推,直到幸存le......
  • 使用Python+moviepy做音频的淡入淡出效果
    一、音频的淡入效果frommoviepy.editorimport*au=AudioFileclip("/home/Download/test.mp3")au=au.fx(afx.audiofadein,duration=1)#一秒钟的淡入效果au.write_audiofile("/home/Download/fade.mp3")二、音频的淡出效果frommoviepy.editorimport*au=Audio......
  • 使用Python操作MySQL的多种方式
    目录MySQL简介安装与配置使用MySQLConnector/Python连接数据库执行SQL语句处理查询结果事务管理使用SQLAlchemy安装SQLAlchemy连接数据库定义模型执行查询事务管理使用DjangoORM安装Django配置数据库定义模型执行查询事务管理总结MySQL简介MySQL是一种开源的关系......
  • Python和AI库NumPy(三):数组形状与变换
    目录1.数组的基础形状操作1.1查看数组的形状1.2改变数组的形状2.数组的转置与轴交换2.1数组的转置2.2交换数组的轴3.数组的合并与分割3.1数组的水平与垂直合并3.2数组的分割4.高级数组变换技巧4.1广播机制(Broadcasting)4.2使用expand_dims()和squeeze()......
  • Adobe Premiere Pro(简称PR)中文版软件安装包
    一、简介AdobePremierePro(简称PR)是由Adobe公司开发的一款专业的视频编辑软件。无论是电影、电视、网络视频还是社交媒体内容,PremierePro都能提供从采集到剪辑、调色、音频处理、添加字幕以及输出的全套解决方案。软件提供了丰富的视频特效、转场效果和音频效果,可以与Adobe......
  • Adobe Premiere Pro(PR2024)中文版软件下载安装
    一、AdobePremierePro软件下载点击此处二、AdobePremierePro软件介绍AdobePremierePro是一款由Adobe公司开发的视频编辑软件,它具有丰富的编辑功能,可以帮助用户创建高质量的视频作品。PR软件支持多种视频格式,可以方便地导入和编辑各种视频素材。同时,PR软件还提供了强大......