做为普遍应用的警告标志,与字面意思不一样,代码异味并非指代码中须要当即注意的漏洞。相反,它反映出代码中更深层次的问题,更确切地说是代码中的裂缝,若是不加以纠正,这些问题可能会在将来致使更严重的后果。程序员
代码异味是弱点或设计缺陷的标志,可能会在可读性、可维护性和可拓展性上致使问题,一般是由不当作法和未使用正确的工具致使的。面试
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大厂面试题戳领