InfoQ Geekathon 大模型技术应用创新大赛 了解详情
写点什么

Python 编程中的反模式

  • 2014-07-14
  • 本文字数:1733 字

    阅读完需:约 6 分钟

Python 是时下最热门的编程语言之一了。简洁而富有表达力的语法,两三行代码往往就能解决十来行 C 代码才能解决的问题;丰富的标准库和第三方库,大大节约了开发时间,使它成为那些对性能没有严苛要求的开发任务的首选;强大而活跃的社区,齐全的文档,也使很多编程的初学者选择了它作为自己的第一门编程语言。甚至有国外的报道称,Python 已经成为了美国顶尖大学里最受欢迎的编程入门教学语言。


要学好一门编程语言实属不易,在初学阶段,就纠正一些错误的做法,对今后的深入学习至关重要。有一位叫 Constantine Lignos 的博主,他是宾夕法尼亚儿童医院放射研究部门的博士后研究员,他最近撰写了一篇很有意义的文章,列举了初学 Python 的学生们最常犯的错误,并对这些错误进行了分类和剖析,其内容提纲挈领,非常值得每个 Python 初学者学习。

这篇文章给出了一些在 Python 初学者中很常见的反模式,反模式通常是指那些不符合习惯或者会导致糟糕后果的用法。Lignos 把他总结的反模式分成了四大类——迭代、性能、变量的漏洞和编程风格。下面我们逐一来看一个例子,理解这些反模式到底“反”在什么地方。

迭代

当我们需要简单迭代一个数量范围的时候,Python 给了我们一个非常好用的函数:range。Lignos 观察到有些初学者喜欢用 range 来迭代列表的下表,像下面这种形式:

复制代码
for i in range(len(alist)):
print alist[i]

这代码现在还没什么问题,但已经不符合 Python 的习惯了。但下面的代码就有问题了:

复制代码
alist = ['her', 'name', 'is', 'rio']
for i in range(0, len(alist) - 1): # 漏掉了最后一个
print i, alist[i]

我们可以看一下 Python 官方文档 range 的示例

复制代码
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

range 的右区间是不包含在内的,如果受了直觉或其他编程语言的影响,再减 1 就不对了。Lignos 还列举了其他几种错误的迭代模式,我们只要记住,range 应该用在迭代一个数量范围。

性能

Lignos 给出了两段代码:

复制代码
lyrics_list = ['her', 'name', 'is', 'rio']
words = make_wordlist()
for word in words:
if word in lyrics_list: # 线性时间
print word, "is in the lyrics"

复制代码
lyrics_set = set(lyrics_list)
words = make_wordlist()
for word in words:
if word in lyrics_set: # 常数时间
print word, "is in the lyrics"

哪种模式效率更高?Lignos 注释已经给出了答案。注释的意思是,判断一个元素是否在一组元素中存在,使用 list 的算法复杂度是 O(n),而使用 set 的算法复杂度是 O(1)。那是否 set 永远是优于 list?在其他情况下,应该用哪个数据结构?Python 官方 Wiki 有一份专门各个数据结构操作的时间复杂度的文档供参考,知道参考这份文档比答案本身更重要。至于为什么,只有 Python 的源码才能告诉我们。

变量的漏洞

初学者往往会假设一些不该假设的前提,对一些异常流程考虑不周。Lignos 也给了一个例子:

复制代码
for idx, value in enumerate(y):
if value > max_value:
break
processList(y, idx)

这里 y 如果是空的,那就出问题了,因为 idx 根本得不到定义,最终我们会得到一个 NameError 的异常。比较好的做法是给 idx 一个默认的错误值,在 C 语言里面我们经常喜欢用 -1。下面的代码就考虑得比较全面:

复制代码
def find_item(item, alist):
# 对 Python 来说 None 比 -1 可能更好点
result = -1
for idx, other_item in enumerate(alist):
if other_item == item:
result = idx
break
return result

代码风格

Python 有一份代码风格指导文档 PEP 8 ,这些规则都是有道理的。当初学者不明白为什么的时候,最好的做法就是尽量遵守它,等到有更深入的理解了就会豁然开朗,同事也会明白什么时候可以打破规则。Lignos 引用了这份文档的一些例子,比如,如何测试一个变量是否为空,如果测试一个变量是否为 None 等等。


以上分析了这篇文章中的一些例子,如果希望全面了解,请查看原文。想要学好一门编程语言,学会语法是远远不够的,必须逐步理解语言所依赖的 CPU 体系结构、编译器 / 解释器 / 虚拟机等内容。Lignos 这篇文章虽然没有深入剖析 Python 的实现,但是对于入门者的帮助是非常明显的,当初学者有了一定经验后,对一些问题都可以做深入挖掘,引出 Python 实现层面的问题。

活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2014-07-14 08:015235
用户头像

发布了 77 篇内容, 共 34.6 次阅读, 收获喜欢 24 次。

关注

评论

发布
暂无评论
发现更多内容

WireGuard 教程:使用 DNS-SD 进行 NAT-to-NAT 穿透

米开朗基杨

wireguard

第二章作业二

LouisN

领域的边界,一个小讨论

李小腾

领域驱动设计 DDD

专访京东科技张亮:本土开源需形成吸纳开发者的靶心

京东科技开发者

开源

工业互联网平台:将为“补链”“优链”“强链”提供有力保障

浪潮云

工业互联网

GitHub星标数超4.2万的火爆之作!

博文视点Broadview

五种C语言非数值计算的常用经典排序算法

华为云开发者联盟

算法 记录 C语言 排序 非数值计算

智能对联模型太难完成?华为云ModelArts助你实现!手把手教学

华为云开发者联盟

人工智能 modelarts mindspore Seq2Seq

分盘存储:实现数据库备集群备份文件分散存储

华为云开发者联盟

数据库 数据 容灾 集群 分盘存储

勿让 Docker Volume 引发 Terminating Pod

黄久远

Docker 云计算 Kubernetes 容器 云原生

Elasticsearch Document 增删改内部原理

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试 2月春节不断更

科普篇:新冠疫苗解读

石云升

28天写作 2月春节不断更 新冠疫苗

PowerApps画布应用编码规范和指南

Changwei™

低代码 企业应用 Power Platform PowerApps

💻 一文读懂两台计算机之间是如何通信的

飞天小牛肉

面试 计算机网络 2月春节不断更

如何理解Linux系统SSH协议和原理

Changing Lin

Linux 2月春节不断更

任务悬赏系统软件开发

v16629866266

Java 多线程上下文传递在复杂场景下的实践

vivo互联网技术

Java 架构 编程语言 多线程高并发

单例模式原来是这么简单?!

后台技术汇

28天写作 2月春节不断更

DIY一款能随周围环境变化的智能灯泡,求婚必备!

IoT云工坊

人工智能 物联网 人脸识别 sdk IoT App

python subprocess-更优雅的创建子进程

jeffery

Python

这一年,像踏码进货一样!

小傅哥

Java 小傅哥 技术成长 平台羊毛

话题讨论 | 你现在还会推荐亲朋做程序员吗?

石云升

话题讨论 2月春节不断更

运动健身市场越来越大,你的客户却越来越少?

IoT云工坊

人工智能 App 物联网 健身房 智能健身房

如何理解平行宇宙

陈东泽 EuryChen

科普 物理 平行宇宙 平行世界

谁再把IDEA的Project比作Eclipse的Workspace,我就跟谁急

YourBatman

eclipse IntelliJ IDEA Project Workspace

【Animate.css】CSS动画库

德育处主任

CSS css3 html/css 28天写作

作业二

KYoKO

Java之五种遍历Map集合的方式

华为云开发者联盟

Java 对象 Iterator 内容合集

两个高频设计类面试题:如何设计HashMap和线程池

yes

面试 hashmap 线程池

博文视点算法书单|让算法学习不再难

博文视点Broadview

MySQL字段类型最全解析

Simon

MySQL 数据库数据类型

  • 扫码添加小助手
    领取最新资料包
Python编程中的反模式_Python_曹知渊_InfoQ精选文章