Python 反设计模式2025年3月17日 | 阅读 8 分钟 反模式的作用与预定义的 设计模式 相反。 我们可以通过名称来推测它的功能。 在这种方法中,对于常见的问题,有各种各样的技术,这些技术可以被形式化,并且可以成为良好的开发实践。 通常,反模式被认为是不良的。 让我们了解一些常见的反设计模式。 反模式的重要特征这种方法有一些在编程过程中需要考虑的特征。 这些特征如下所示。 正确性反模式将我们的代码分解成更小的块,这样我们就可以做错事。 以下是访问类外部的私有成员的简单示例。 示例 在上面的代码中,我们试图直接访问私有类成员。 这将引发错误。 可维护性如果程序易于理解、易于调试,并且可以在需要时进行更改,则我们可以认为程序是可维护的。 反模式使程序难以维护。 导入模块可以成为可维护性的一个合适的例子。 一个模块由许多有用的预定义函数组成,用于执行特定的任务。 众所周知,Python 有许多预定义的模块和库,这使得程序易于维护。 让我们了解下面的例子。 示例 - 可读性反模式在代码中创建了复杂性,因此代码变得难以阅读和理解。 程序员可能会犯一些常见的错误,这些错误会降低代码的可读性。 这些常见错误包括不使用 zip() 方法来迭代一对列表,请求许可而不是原谅,不使用字典推导式,使用 type() 来比较类型等。 让我们了解下面的例子。 示例 - 在上面的代码中,我们使用了 zip() 方法来比较列表对。 这是一个好习惯。 我们在列表对上使用了 zip(nums, letters) 函数的 for 循环。 Python 将自动将第一个变量分配为下一个值,将第二个变量分配为第二个列表的下一个值。 安全性众所周知,Python 是一种高级的、动态类型的语言,这意味着用户可以更改其代码的行为,甚至可以在运行时执行代码。 使用 exec 可能会在代码中创建安全问题。 以下是一个示例。 示例 - 好的做法 性能性能是任何 编程语言 中的一个大问题。 我们可以使用适当的函数和库来获得良好的性能。 如果我们不使用 iteritems() 来迭代大型字典,或者使用列表中的 key 来检查 key 是否包含在列表中,则性能可能会受到影响。 让我们了解下面的例子。 示例 - 在上面的代码中,我们已将列表更改为集合。 它在幕后更有效率。 在列表中,Python 会将每个数字与目标数字进行比较,但是使用集合;它可以直接访问目标数字。 Python 中一些重要的反模式以下是 Python 中最常见的反模式。
不使用 with 语句打开文件是一个不好的做法。 我们需要记住通过调用 close() 函数来关闭文件。 如果我们显式关闭文件,则在资源关闭之前可能会出现异常。 因此,我们应该使用该语句打开文件,因为它实现了上下文管理协议,该协议会释放资源。 我们不需要显式关闭资源。 让我们了解下面的例子。 不好的做法 好的做法
这是我们大多数人至少犯过一次的最常见的错误类型。 当我们调试代码并发现错误时,我们可能会将调试器留在生产代码中。 这会影响代码的行为。 强烈建议在检查代码之前审核代码以消除调试器的调用。
当我们通过调用 list() 而不是使用空字面量来初始化空列表时,它会使程序相对变慢。 因此,建议使用空字面量来声明列表、字典和元组。 让我们看下面的例子。 不好的做法 好的做法
避免在代码中使用 get() 方法会影响可读性。 我们创建一个变量并为其分配默认值。 当我们检查字典中的特定键时,如果该键可用,则该键的值将分配给变量的值。 我们可以使用字典的 get() 方法轻松地做到这一点。 让我们了解下面的例子。 不好的做法 好的做法
返回多个类型的对象会使代码混乱且难以理解。 这也可能是导致难以解决的错误的根源。 一个函数可以返回一个值而不是给定的类型(例如,整数、常量、列表、元组); 调用者检查将检查要返回的值。 建议仅返回该函数的一个类型的对象。 让我们看下面的例子。 不好的做法 好的做法
Python 提供了诸如 all、any、enumerate、iter、itertools.cycle、itertools.accumulate 之类的函数,它们可以直接与生成器表达式一起使用。 我们不需要将推导式与这些方法一起使用。 all() 和 any() 函数也用于提供短路,但是如果使用了推导式,则会丢失此行为。 让我们看下面的例子。 不好的做法 好的做法
我们不需要在对 dict、list 或 set 的调用中使用生成器的表达式,因为这三个都有推导式。 因此,建议使用推导式而不是生成器。 让我们了解下面的例子。 不好的做法 好的做法
字典的 item() 方法返回一个带有键值元组的可迭代对象。 可以使用 for 循环解包元组。 这是一个简单、动态且推荐的方法。 让我们了解下面的例子。 不好的做法 好的做法
Python 提供了将 else 语句与循环一起使用的功能。 当循环为空并且最终在执行后循环为空时,将执行 else 块。 这似乎是预期的行为,但大多数情况下这不是预期的行为。 因此,如果我们将 else 与 Python 循环一起使用,则应在循环中使用 break 语句。 让我们了解下面的示例。 不好的做法 示例 - 输出 This list has the number This list does NOT has the number 上面的代码演示了,我们没有在 for 循环中使用 break 语句。 现在尝试理解输出; 当我们在给定的列表中找到 searched_number 时,我们希望循环仅打印 "This list has the number," ,但它会打印两个结果。 这是因为列表变空了; else 块也被执行。 好的做法 输出 This list has the number
这是程序员在编写代码时不太关心的最常见的反模式,尤其是初学者只关注缩进,并且他们混合了制表符和空格。 让我们了解下面的例子。 不好的做法 输出 Hello, World! Goodbye, World! 好的做法 输出 Hello, World! Goodbye, World!
通常,我们更喜欢一种明显的方式来获取列表的所有元素。 我们总是“创建一个循环,该循环使用递增索引来访问循环中列表的每个元素”。 这不是访问列表中每个元素的好方法。 我们应该使用 enumerate() 函数。 让我们了解下面的例子。 不好的做法 好的做法
Python lambda 函数也被称为 匿名 函数,这是相对于 def 函数 最大的优势。 作为匿名,lambda 方法可以分配给任何更大的表达式。 分配 lambda 方法会消除 lambda 函数的好处。 如果需要将 lambda 方法分配给一个变量,则使用 def 语句创建一个等效的方法。 让我们了解下面的例子。 不好的做法 好的做法
当一个类方法不包含对类的任何引用 (self) 并且前面没有 @staticmethod 时,它 将引发“方法可能是一个函数”错误。 此错误并不严重,但我们应该检查代码以确定该函数是否真的需要成为类方法。 让我们了解下面的例子。 不好的做法 好的做法 或 下一主题# |
我们请求您订阅我们的新闻通讯以获取最新更新。