五大代码异味:你需要提高警惕了!

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 代码异味是弱点或设计缺陷的标志,可能会在可读性、可维护性和可拓展性上导致问题,通常是由不当做法和未使用正确的工具导致的。


 



image


作为广泛应用的警告标志,与字面意思不同,代码异味并不是指代码中需要立即注意的漏洞。相反,它反映出代码中更深层次的问题,更确切地说是代码中的裂缝,如果不加以纠正,这些问题可能会在未来导致更严重的后果。


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


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


可变默认参数


在Python中,使用默认参数是一个很常见的操作,你可以设置一个预定值,并在调用时选择更改。这在设置文字、数字或布尔值时很有用,因为有助于避免出现较长的有冗余值的参数列表。


但是将可变的值设置为默认参数可能是危险的,并且会导致bug。来看以下示例:


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能提供一个元组的优势,该元组负责同时跟踪索引值和元素。除了更简便,优化程度还更高,它还提供了可选的第二个参数来设置数值。


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"#use this
list(map(str.lower, names))

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

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


嵌套分析也需要关注,因为这可能导致可读性问题,知道什么时候使用它,什么时候回退到for循环上是很重要的。


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


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


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


跟踪它的状态会很棘手,因为你永远不知道谁可能会改变它。如果开始到处使用全局变量,命名冲突则会导致命名空间受到不好的影响。



image


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


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


原文发布时间:2020-08-02
本文作者:读芯术


目录
相关文章
|
2月前
|
数据可视化 关系型数据库 MySQL
揭秘“商业园区综合管理平台”的无代码开发流程!
​ 本文中的素材来自我在某国资投资集团朋友小赵的“有偿”投稿,要知道现在的商业园区也正在经历数字化改造,面对多商场、多店铺的复杂管理需求,各类商管集团纷纷进行线上互联网管理模式的转型。 这份素材有何不同之处呢?因为他们走了一条开发新路子——无代码开发。小赵作为项目经理主要和无代码平台方做对接,他对领导决议的态度也从一开始的3分震惊7分质疑转变为现在的逐步认可,甚至自己也在尝试搭建,这些都被我看在眼中。 最离谱的是,期项目从BIM驾驶舱到经营分析大屏,以及一套含项目/合同/工单等10多个模块的综合运营管理平台,一个多月就被他们搞定了。作为一个自媒体技术博主的我,敏锐的嗅到素材的味道,直接就去联
62 0
|
1月前
|
人工智能 持续交付 Docker
探索现代软件开发的五大趋势
在快速变化的技术领域,软件开发正经历前所未有的变革。本文探讨了塑造未来技术景观的五大趋势:微服务架构的兴起,让应用更模块化;容器化与Docker简化部署;CI/CD提升软件交付速度;低代码/无代码平台降低开发门槛;AI与ML自动化测试和代码生成。掌握这些趋势将帮助开发者保持竞争力。
|
2月前
|
机器学习/深度学习 数据采集 人工智能
下一个数据战略的6个战略要点
下一个数据战略的6个战略要点
|
3月前
|
监控
信息系统 项目十大管理和五大过程
信息系统 项目十大管理和五大过程
|
5月前
|
新零售 供应链
九星创客新零售模式开发|成熟案例|项目需求
未来新零售对消费者最好的服务方式是“你需要,我送到”
|
边缘计算 供应链 网络协议
谈谈企业上云的四大重点与五大阶段
企业从工业云进化为工业互联网,需要经历五个阶段 前一篇文章,我们了解了企业为什么上云以及企业上云的好处。今天,老王侧重跟大家分享相关部门对企业上云的总体规划及部署,同时也让大家对企业上云的总体进程有个答题了解。明白这些,便于企业老板对今后的企业发展规划、运营上云以及融资需求等,有一个整体把握。
411 0
谈谈企业上云的四大重点与五大阶段
|
传感器 存储 人工智能
带你读《创新之巅: 未来十年重构商业的六大战略性技术》第一章未来十年重构商业的 六大技术1.AI 启用战略
《创新之巅: 未来十年重构商业的六大战略性技术》第一章未来十年重构商业的 六大技术1.AI 启用战略
|
数据可视化 程序员 开发者
不懂代码,他怎么开发了20多个政务应用?
灰西装、寸头、无边框眼镜,看起来与程序员气质迥异的陶海锋,不会读写编程代码,却解锁了一项颇有反差感的“互联网新成就”:为部门的同事们开发了二十多个办公应用。
4804 0
不懂代码,他怎么开发了20多个政务应用?
|
消息中间件 IDE Java
从架构到代码:软件开发最新趋势解析
在2020年4月份,InfoQ发布了软件开发架构与设计趋势图,将目前的软件架构与设计等技术分为了四个所处阶段,即创新者、早起采用者、早期大众和晚期大众。本文中,阿里巴巴美国团队资深技术专家陈立兵(花名:雷卷)就为大家分享了对于软件开发最新趋势的解析。
1063 0
从架构到代码:软件开发最新趋势解析