五大代码异味:你须要提升警戒了!

做为普遍应用的警告标志,与字面意思不一样,代码异味并非指代码中须要当即注意的漏洞。相反,它反映出代码中更深层次的问题,更确切地说是代码中的裂缝,若是不加以纠正,这些问题可能会在将来致使更严重的后果。程序员

代码异味是弱点或设计缺陷的标志,可能会在可读性、可维护性和可拓展性上致使问题,一般是由不当作法和未使用正确的工具致使的。面试

Python是最流行的语言之一,这在很大程度上与其至关容易的学习曲线和高度伪英语句法有关,而这却容易使人陷入单一的作事方法。本文中,咱们将了解一些典型的Python代码异味案例以及如何避免它们。安全

可变默认参数

在Python中,使用默认参数是一个很常见的操做,你能够设置一个预约值,并在调用时选择更改。这在设置文字、数字或布尔值时颇有用,由于有助于避免出现较长的有冗余值的参数列表。架构

可是将可变的值设置为默认参数多是危险的,而且会致使bug。来看如下示例:app

def addElements(a=[]):
    a.append(5)
    return aaddElements()
# [5]
addElements()
# [5, 5]

相同的函数在每次调用时给出不一样的结果。Python中可变默认值的问题是它们只在定义函数时计算一次。每次调用函数时,使用变异值,可能会致使意外的问题,由于跟踪函数调用真的很麻烦。运维

所以,使用None做为默认值,并在函数中分配可变变量是更安全的,由于你不会以可维护性问题结束,只有在肯定须要时才使用可变的默认参数。分布式

选择 range 而不是enumerate

Python的for循环不是最经常使用的代码编写方式,但有时也会须要到。如今,Python中的for 循环的运行与其余语言不一样,你可能会本能地以非惯用的方式编写传统风格的range(len()),以下所示:函数

names =["a", "b", "c"]for i in range(len(names)):
    print(i, names[i])

重复基于C-style索引的循环是至关常见的,但这是一种不当作法。其迫使你经过显式索引变量访问元素,因此它不只Python特性不明显,并且还存在可读性问题。工具

使用enumerator能提供一个元组的优点,该元组负责同时跟踪索引值和元素。除了更简便,优化程度还更高,它还提供了可选的第二个参数来设置数值。oop

for i, name in enumerate(names):
   print(i, name)

忽略内置函数和过分循环

循环不是不能用,但在其中应用转换操做时,它可能会致使冗长的条件代码。在这种状况下,不要忽略已经可使用的内置函数,如map()filter()和reduce(),这是很是重要的。更重要的是,Python提供了列表解析,这显然是最具Python特性的替换循环方法。

嵌套for循环是代码异味的另外一个典型例子。Python程序员在进行模式匹配或一块儿运行多个迭代时很容易中枪。下列代码一旦再加几行就会看起来不美观:

for x in listA:
    for y in listB:
        r.append((x, y))

使用itertools不只能够提升性能,还更简洁明了。看看上面的代码在itertools.product()中有多整洁:

for x, y in itertools.product(listA,listB):    
    r.append((x, y))

经过使用上面的product,也能够很容易地将其传递到其余高阶函数中。同时在多个列表上同时迭代时,使用zip()函数也不错(如需索引,还可使用enumerator)。

滥用列表解析

列表解析能灵活建立列表,功能强大,但很容易被误用或滥用,来看一些案例。

在不须要时过分进行列表解析
一般,咱们开始沉迷于使用列表解析是为了尝试花哨的东西,而不是真须要它。好比在简单的状况下可使用列表构造函数:

names =["A","B","C"][x.lower() for x in names]#use this
list(map(str.lower, names))

在实际不存储时使用列表解析

列表解析有助于轻松定义和建立列表,但它们始终存储于内存中。若是不使用系统进程,将有可能损害大数量的数据。所以,使用生成器表达式是更好的选择,由于它按需一次加载一个值。

嵌套分析也须要关注,由于这可能致使可读性问题,知道何时使用它,何时回退到for循环上是很重要的。

喜欢布尔标志参数和全局变量

布尔是最容易学习的数据类型。在Python中,提供命名参数使工做轻松得多。可是,它们很容易产生嵌套if else块的复杂代码并致使可读性问题。多个布尔存在隐藏的依赖关系,会产生一些问题。于是最好使用枚举,而不是多布尔逻辑。Enum数据类型是可扩展的,能够确保更好的代码结构。

全局变量在全部语言中都是麻烦的,Python也是如此。虽然有时咱们确实须要使用它们,但将其误用做传递或访问数据的快捷方式可能很危险,由于它可变。

跟踪它的状态会很棘手,由于你永远不知道谁可能会改变它。若是开始处处使用全局变量,命名冲突则会致使命名空间受到很差的影响。

咱们都见过代码异味,神秘的注释、多余的字符串文字和神奇的数字也算代码异味。在编写注释时,重要的是要说明“为何”部分,由于“什么”部分应该从代码自己获得解释。

你得学会快速定位到代码异味并将其去除。

※更多文章和资料|点击后方文字直达 ↓↓↓
100GPython自学资料包
阿里云K8s实战手册
[阿里云CDN排坑指南] CDN
ECS运维指南
DevOps实践手册
Hadoop大数据实战手册
Knative云原生应用开发指南
OSS 运维实战手册
云原生架构白皮书
Zabbix企业级分布式监控系统源码文档
云原生基础入门手册
10G大厂面试题戳领
相关文章
相关标签/搜索