你在滥用Python吗?初学者常会遇到的5个情景
云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!
Python拥有众多学习者,可谓是如今许多编程初学者的首选语言。易学的语法、丰富的库和大量的社区都是Python飞速发展的主要原因。
6年前,在我掌握了一系列Java之后接触到Python时,经常发现自己在写Python代码时脑子里还想着Java。作为一个新手,我没有充分利用Python的优点,甚至在某些情况下,我滥用了它。
现在,我仍然看到一些初学者在没有先花时间阅读最佳实践和建议的情况下就开始用Python写代码。为解决这个问题,我列出了下面5个滥用Python的情景,并给出了相关改进建议。
1.使用列表时
列表允许存储各种数据类型的元素且不限制大小,尽管这种灵活性使列表成为收集数据的首选,但实际上仍有一些使用和不使用它的最佳实践情景。
在存储具有相同性质(数据类型和含义)的元素时,应该使用列表。Python不会通过编程来限制这一点,在列表中存储单个自然项让开发人员的工作更轻松。开发人员很容易预测将来列表会有哪些项,并确信地编写脚本。
思考下面的物品列表。这个列表并不包含单一性质的项目,开发人员无法确定该列表是否包含房屋部件、尺寸或其他东西,因此他应该分别处理不同的项目:
list_of_things = [ Door , 2, Window , True, [2.3, 1.4])]
思考下面的水果列表和分数列表。从前两个项目中,你很容易推断出第一个列表会始终包含水果名字,而第二个列表始终包含分数值:
list_of_fruits = [ apple , orange , pear , cherry , banana ] list_of_scores = [80, 98, 50, 55, 100]
在存储具有不同含义或数据类型的项目时,使用元组更合适。元组不具备在不创建新对象的情况下,提供存储不受限项目的灵活性(因为元组是不可变的)。
2.迭代连接字符串时
在Python中所有东西都是对象,包括可变和不可变对象。每当更新分配给对象的值时,不可变对象需创建新对象,而可变对象则不需要。
假设你想在一个字符串中生成整个字母表。因为字符串是不可变对象,所以每当使用“+”运算符连接字符串值时,就会得到一个新的对象。
one_line_alphabet = for letter_index in range(ord( a ), ord( z )): one_line_alphabet +=chr(letter_index)
Join函数是连接字符串的首选方法。使用join函数可将计算时间缩短约3倍。在我做的一项测试中,迭代连接100万个字符串值耗时0.135秒,若使用join( )函数则只需0.044秒。
small_letters = [chr(i) for i inrange(ord( a ), ord( z )+1)] single_line_alphabet = .join(small_letters)
因此,需要连接字符串列表时请使用join函数。若使用join函数连接几个字符串,这并不会直观感受到性能的差异。若要连接几个字符串值,请使用.format而不是“+”运算符。例如:
name = John surname = Doe full_name = {name} {surname} .format(name=name, surname=surname)
3.读写文件时
若要使用Python读写文件,首先需要用内置的open函数打开文件。打开文件,读取或写入内容以及关闭文件。进行操作时,可能会出现一些问题,比如忘记关闭文件和异常处理失败。
操作完成后,若忘记关闭文件会导致后续问题。比如,如果在写入文件后忘记关闭该文件,那么写入操作将不会保存至文件中,并且在文件仍然保持打开状态时,你将保留在计算机中分配的资源。如果在处理文件时,没有手动处理异常和错误,那么文件将保持打开的状态。
f = open(file= file.txt , mode= r ) lines = f.readlines() ... f.close()
建议在打开文件时使用with关键字。with是一个上下文管理器,它能封装代码并能确保自动处理异常。比如,当你读写文件时,with-body中可能出现的任何故障,都能自动处理异常,并且始终保持该文件关闭。
with open( file.txt ) as f: read_data = f.read() ...
如果跳过with时,你需要自己处理一切,关闭文件和异常处理都得亲自处理。with会让你的生活更轻松,让情况得以控制。
4.跳过生成器时
在许多情景中,你需要生成一个值列表,稍后将在脚本中使用这些值。比如,你需要为前100个数字生成所有3个数字的组合。
combinations = [] value = 100 for i in range(value): for j in range(value): for k in range(value): combinations.append((i, j,k))
当执行的命令完成时,列表组合将包含1M元组,每个元组有3个整型值。这些值将保存在内存中,直到被删除。使用sys模块中的getobjectsize函数检查对象大小,结果为8.29MB。
不再使用列表存储值并将它们全部保存至内存,可以创建一个生成器,每当你使用它时,将生成1个组合。这能减少内存消耗并提高运行速度。
defgenerate_combinations_of_three(value): for i in range(value): for j in range(value): for k in range(value): yield (i, j, k)gen =generate_combinations_of_three(100)next(gen) # yields (0, 0, 0) next(gen) # yileds (0, 0, 1) ...
所以,尽可能多地使用生成器。时刻牢记内存容量是有限的,并尽可能优化内存使用。请使用生成器,特别是在开发可伸缩的解决方案时。
5.使用推导式时
有一些程序员,他任何用Python编写代码都遵循Python之禅(The Zen of Python)的准则。如果是使用Python的新手,可能会倾向于夸大Python之禅的某些观点,而在其他方面避重就轻。
这一点在逐渐了解推导式时最容易注意到——你倾向于翻译推导式中的“每一个”循环。假设你有一个三维的数字矩阵,你很可能会想将其平面化。
matrix = [[[ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ]], [[ 10, 20, 30 ], [ 40, 50, 60 ], [ 70, 80, 90 ]]]
使用列表推导式,平面化过程如下:
flatten_list = [x for sub_matrix inmatrix for row in sub_matrix for x in row]
使用循环,平面化过程如下:
flatten_list = [] for sub_matrix in matrix: for row in sub_matrix: for x in row: flatten_list.append(x)
列表式很酷,但可读的代码更酷。不要试图总是让自己使用列表式,即使这样做可能需要编写更少的代码,也不会损失代码的可读性。
不论是否有编程经验,每当尝试使用一种新的编程语言时,请一定要抽出时间阅读最佳实践。每种编程语言都有其独特之处,所以要确保在适当的场景合理地运用它们。
Python致力于帮助程序员更高效便捷地完成工作,我们不能忽视可能对代码生命期产生负面影响的小决策。请尽可能寻找更好的和最佳的解决方案,这是程序员的工作使命。
【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
正确入门Service Mesh:起源、发展和现状
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 阿里妹导读:Service Mesh早已不是一个新兴的概念,但大家对Service Mesh的探索依然火热。本文将依次讲解Service Mesh的定义(什么是Service Mesh)、起因(为什么需要Service Mesh)和现状(Service Mesh的主流实现),希望通过浅显易懂的介绍,尽量帮助大家更好地理解Service Mesh。 引言 随着云原生时代的来临,微服务架构与容器化部署模式越来越流行,从原来的新潮词汇慢慢演变成为现代IT企业的技术标配。曾经被认为理所当然的巨无霸单体应用,被拥抱了微服务的架构师们精心拆分成了一个又一个小而独立的微服务,接着再被拥抱了容器化的工程师们打包成了自带依赖的Docker镜像,最后通过某种神秘的DevOps流水线持续运送到前线 —— 也就是无人不知的 —— 风暴降生·谷歌之子·打碎镣铐者·云时代操作系统·Kubernetes —— 之中部署和运行。 听上去似乎一切都很美好?显然不是,这世上永远没有免费的午餐。所有美好的东西都会有它的阴暗面...
- 下一篇
What’s New in Dubbo-go v1.5
引语 计算机技术浪潮每 10 年都有一次技术颠覆,相关知识体系最迟每 5 年都会革新一次,大概每两年贬值一半,在应用服务通信框架领域亦然。凡是有长期生命的通信框架,大概有 5 年的成长期和 5 年的稳定成熟期。每个时代都有其匹配的应用通信框架,在 20 年前的 2G 时代,强跨语言跨平台而弱性能的 gRPC 是不会被采用的。 每个通信框架,不同的人从不同角度看出不同的结论:初学者看重易用易学,性能测评者注重性能,应用架构师考虑其维护成本,老板则考虑则综合成本。一个应用通信框架的性能固然重要,其稳定性和进化能力更重要,得到有效维护的框架可在长时间单位内降低其综合成本:学习成本、维护成本、升级成本和更换成本。 什么是 Dubbo-go?第一,它是 Dubbo 的 Go 语言版本,全面兼容 Dubbo 是其第一要义。第二,它是一个 Go 语言应用通信框架,会充分利用作为云原生时代第一语言---Go 语言的优势,扩展 dubbo 的能力。 2008 年诞生的 Dubbo 已有十多年历史,依靠阿里和其社区,历久弥新。2016 年发布的 Dubbo-go 也已进入第五个年头,如今全面兼容 Dubb...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路