0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Python工匠是什么?变量和代码质量

马哥Linux运维 来源:未知 作者:李倩 2018-05-08 14:25 次阅读

Python 工匠』是什么?

我一直觉得编程某种意义上是一门『手艺』,因为优雅而高效的代码,就如同完美的手工艺品一样让人赏心悦目。

在雕琢代码的过程中,有大工程:比如应该用什么架构、哪种设计模式。也有更多的小细节,比如何时使用异常(Exceptions)、或怎么给变量起名。那些真正优秀的代码,正是由无数优秀的细节造就的。

『Python 工匠』这个系列文章,是我的一次小小尝试。它专注于分享 Python 编程中的一些偏『小』的东西。希望能够帮到每一位编程路上的匠人。

变量和代码质量

作为『Python 工匠』系列文章的第一篇,我想先谈谈 『变量(Variables)』。因为如何定义和使用变量,一直都是学习任何一门编程语言最先要掌握的技能之一。

变量用的好或不好,和代码质量有着非常重要的联系。在关于变量的诸多问题中,为变量起一个好名字尤其重要。

如何为变量起名

在计算机科学领域,有一句著名的格言(俏皮话):

There are only two hard things in Computer Science: cache invalidation and naming things. 在计算机科学领域只有两件难事:缓存过期 和 给东西起名字

— Phil Karlton

第一个『缓存过期问题』的难度不用多说,任何用过缓存的人都会懂。至于第二个『给东西起名字』这事的难度,我也是深有体会。在我的职业生涯里,度过的作为黑暗的下午之一,就是坐在显示器前抓耳挠腮为一个新项目起一个合适的名字。

编程时起的最多的名字,还数各种变量。给变量起一个好名字很重要,因为好的变量命名可以极大的提高代码整体可读性。

下面几点,是我总结的为变量起名时,最好遵守的基本原则。

1. 变量名要有描述性,不能太宽泛

在可接受的长度范围内,变量名能把它所指向的内容描述的越精确越好。所以,尽量不要用那些过于宽泛的词来作为你的变量名:

GOOD:day_of_week,hosts_to_reboot,expired_cards

BAD:day,host,cards,temp

2. 变量名最好让人能猜出类型

老司机们都知道,Python 是一门动态类型语言,它(至少在PEP 484出现前)没有变量类型声明。所以当你看到一个变量时,除了通过上下文猜测,没法轻易知道它是什么类型。

不过,人们对于变量名和变量类型的关系,通常会有一些直觉上的约定,我把它们总结在了下面。

『什么样的名字会被当成 bool 类型?』

布尔类型变量的最大特点是:它只存在两个可能的值『是』或『不是』。所以,用is、has等非黑即白的词修饰的变量名,会是个不错的选择。原则就是:让读到变量名的人觉得这个变量只会有『是』或『不是』两种值。

下面是几个不错的示例:

is_superuser:『是否超级用户』,只会有两种值:是/不是

has_error:『有没有错误』,只会有两种值:有/没有

allow_vip:『是否允许 VIP』,只会有两种值:允许/不允许

use_msgpack:『是否使用 msgpack』,只会有两种值:使用/不使用

debug:『是否开启调试模式』,被当做 bool 主要是因为约定俗成

『什么样的名字会被当成 int/float 类型?』

人们看到和数字相关的名字,都会默认他们是 int/float 类型,下面这些是比较常见的:

释义为数字的所有单词,比如:port(端口号)、age(年龄)、radius(半径)等等

使用 _id 结尾的单词,比如:user_id、host_id

使用 length/count 开头或者结尾的单词,比如:length_of_username、max_length、users_count

注意:不要使用普通的复数来表示一个 int 类型变量,比如apples、trips,最好用number_of_apples、trips_count来替代。

其他类型

对于 str、list、tuple、dict 这些复杂类型,很难有一个统一的规则让我们可以通过名字去猜测变量类型。比如headers,既可能是一个头信息列表,也可能是包含头信息的 dict。

对于这些类型的变量名,最推荐的方式,就是编写规范的文档,在函数和方法的 document string 中,使用 sphinx 格式(Python 官方文档使用的文档工具)来标注所有变量的类型。

3. 适当使用『匈牙利命名法』

第一次知道『匈牙利命名法』,是在Joel on Software 的一篇博文中。简而言之,匈牙利命名法就是把变量的『类型』缩写,放到变量名的最前面。

关键在于,这里说的变量『类型』,并非指传统意义上的 int/str/list 这种类型,而是指那些和你的代码业务逻辑相关的类型。

比如,在你的代码中有两个变量:students和teachers,他们指向的内容都是一个包含 Person 对象的 list 。使用『匈牙利命名法』后,可以把这两个名字改写成这样:

students ->pl_studentsteachers ->pl_teachers

pl 是person list的首字母缩写。变量名被加上前缀后,当你看到以pl_打头的变量时,就能知道它所指向的值类型了。

很多情况下,使用『匈牙利命名法』是一个不错的注意,它可以改善你的代码可读性,尤其在那些变量众多、同一类型多次出现时。注意不要滥用就好。

4. 变量名尽量短,但是绝对不要太短

在前面,我们提到要让变量名有描述性。如果不给这条原则加上任何限制,那么你很有可能写出这种描述性极强的变量名:how_much_points_need_for_level2。如果代码中充斥着这种过长的变量名,对于代码可读性来说是个灾难。

一个好的变量名,长度应该控制在两到三个单词左右。比如上面的名字,可以缩写为points_level2。

绝大多数情况下,都应该避免使用那些只有一两个字母的短名字,比如数组索引三剑客i、j、k,用有明确含义的名字,比如 persion_index 来代替它们总是会更好一些。

使用短名字的例外情况

有时,不能使用短名字的原则也会有一些例外。当一些意义明确但是较长的变量名重复出现时,为了让代码更简洁,使用短名字缩写是完全可以的。但是为了降低理解成本,同一段代码内最好不要使用太多这种短名字。

比如在 Python 中导入模块时,就会经常用到短名字作为别名,像 Django i18n 翻译时常用的gettext方法通常会被缩写成_来使用(from django.utils.translation import ugettext as _)

5. 其他注意事项

其他一些给变量命名的注意事项:

同一段代码内不要使用过于相似的变量名,比如同时出现users、users1、user3这种序列

不要使用带否定含义的变量名,用is_special代替is_not_normal

更好的使用变量

前面讲了如何为变量取一个好名字,下面我们谈谈在日常使用变量时,应该注意的一些小细节。

1. 保持一致性

如果你在一个方法内里面把图片变量叫做photo,在其他的地方就不要把它改成image,这样只会让代码的阅读者困惑:『image和photo到底是不是同一个东西?』

另外,虽然 Python 是动态类型语言,但那也不意味着你可以用同一个变量名一会表示 str 类型,过会又换成 list。同一个变量名指代的变量类型,也需要保持一致性。

2. 尽量不要用 globals()/locals()

也许你第一次发现 globals()/locals() 这对内建函数时很兴奋,迫不及待的写下下面这种极端『简洁』的代码:

def render(request, user_id, trip_id): user = User.objects.get(id=user_id) trip = get_object_or_404(Trip, pk=trip_id) is_suggested = is_suggested(user, trip) # 利用 locals() 节约了三行代码,我是个天才! return render(request, 'trip.html', locals())

千万不要这么做,这样只会让读到这段代码的人(包括三个月后的你自己)痛恨你,因为他需要记住这个函数内定义的所有变量(想想这个函数增长到两百行会怎么样?),更别提 locals() 还会把一些不必要的变量传递出去。

更何况,The Zen of Python(Python 之禅)说的清清楚楚:Explicit is better than implicit.(显式优于隐式)。还是老老实实把代码改成这样吧:

return render(request, 'trip.html', { 'user': user, 'trip': trip, 'is_suggested': is_suggested })

3. 变量定义尽量靠近使用

这个原则属于老生常谈了。很多人(包括我)在刚开始学习编程时,会有一个习惯。就是把所有的变量定义写在一起,放在函数或方法的最前面。

def generate_trip_png(trip): path = [] markers = [] photo_markers = [] text_markers = [] marker_count = 0 point_count = 0 ... ...

这样做只会让你的代码『看上去很整洁』,但是对提高代码可读性没有任何帮助。

更好的做法是,让变量定义尽量靠近使用。那样当你阅读代码时,可以更好的理解代码的逻辑,而不是费劲的去想这个变量到底是什么、哪里定义的?

4. 合理使用 dict 来让函数返回多个值

Python 的函数可以返回多个值:

def latlon_to_address(lat, lon): return country, province, city # 利用多返回值一次定义多个变量country, province, city = latlon_to_address(lat, lon)

但是,这样的用法会产生一个小问题:如果某一天,latlon_to_address函数需要返回『城区(District)』时怎么办?

如果是上面这种写法,你需要找到所有调用latlon_to_address的地方,补上多出来的这个变量,否则ValueError: too many values to unpack就会找上你:

country, province, city, district = latlon_to_address(lat, lon)# 或者忽略多出来的返回值country, province, city, _ = latlon_to_address(lat, lon)

对于这种多返回值可能会变动的情况,使用 dict 作为返回值会更方便一些,当你新增返回值时,不会对之前的函数调用产生任何破坏性的影响:

def latlon_to_address(lat, lon): return { 'country': country, 'province': province, 'city': city } addr_dict = latlon_to_address(lat, lon)

这样做的坏处也有,代码兼容性虽然增加了,但是你不能继续用之前x, y = f()的方式一次定义多个变量了。取舍在于你自己。

5. 控制单个函数内的变量数量

人脑的能力是有限的,研究表明,人类的短期记忆只能同时记住不超过十个名字。所以,当你的某个函数过长(一般来说,超过一屏的的函数就会被认为有点过长了),包含了太多变量时。请及时把它拆分为多个小函数吧。

6. 及时删掉那些没用的变量

这条原则非常简单,也很容易做到。但是如果没有遵守,那它对你的代码质量的打击是毁灭级的。会让阅读你代码的人有一种被愚弄的感觉。

def fancy_func(): # 读者心理:嗯,这里定义了一个 fancy_vars fancy_vars = get_fancy() ... ...(一大堆代码过后) # 读者心理:这里就结束了?之前的 fancy_vars 去哪了?被猫吃了吗? return result

所以,请打开 IDE 的智能提示,及时清理掉那些定义了但是没有使用的变量吧。

7. 能不定义变量就不定义

有时候,我们定义变量时的心理活动是这样的:『嗯,这个值未来说不定会修改/二次使用』,让我们先把它定义成变量吧!

def get_best_trip_by_user_id(user_id): user = get_user(user_id) trip = get_best_trip(user_id) result = { 'user': user, 'trip': trip } return result

其实,你所想的『未来』永远不会来,这段代码里的三个临时变量完全可以去掉,变成这样:

def get_best_trip_by_user_id(user_id): return { 'user': get_user(user_id), 'trip': get_best_trip(user_id) }

没有必要为了那些可能出现的变动,牺牲代码当前的可读性。如果以后有定义变量的需求,那就以后再加吧。

结语

碎碎念了一大堆,不知道有多少人能够坚持到最后。变量作为程序语言的重要组成部分,值得我们在定义和使用它时,多花一丁点时间思考一下,那样会让你的代码变得更优秀。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3441

    浏览量

    92488
  • 变量
    +关注

    关注

    0

    文章

    597

    浏览量

    28119
  • python
    +关注

    关注

    52

    文章

    4683

    浏览量

    83503

原文标题:Python 工匠:善用变量来改善代码质量

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    2.1 python常量与变量

    Python语法角度看,PI仍然是一个变量,因为Python根本没有任何机制保证PI不会被改变。你完全可以给PI赋值为10,不会弹出任何错误。所以,用全部大写的变量名表示常量只是一个习
    发表于 02-16 18:34

    工匠机器人 vs 大国工匠

    更多的是用来敲打自己的,让自己坚强的走下去。工匠精神是一种在设计上追求独具匠心,质量上追求精益求精,技艺上追求尽善尽美的精神。工匠精神真的就是一场日益持久的修行,是树立一种对于产品不断持续打磨、持续
    发表于 10-18 14:34

    python环境变量设置

    安装python之后,我们往往面临这样一个问题,在命令行输入“python”,竟然出错,难道是没有安装成功吗?非也,其实是你的系统环境变量没有设置好。今天,小编就来带大家学学python
    发表于 11-20 11:47 2239次阅读
    <b class='flag-5'>python</b>环境<b class='flag-5'>变量</b>设置

    Python变量很难记?常见的解决办法有三种

    在PEP 484中,引入了Type Hints,在PEP 526中引入了Variable Annotations。它使得Python 3.6及以后的Python 代码拥有了“声明”变量
    的头像 发表于 09-30 09:10 2639次阅读

    python设置环境变量

    我们想要运行python,需要安装Python,还要设置一些环境变量1,此电脑,右键属性2、高级系统设置-> 环境变量3、在系统变量中找到p
    发表于 11-10 14:49 784次阅读

    Python私有变量的定义方法

    学过编程语言的人员,都知道私有变量在编程中必不可少,与Java和C语言用private关键字定义私有变量不同,Python是在变量前面加上双横杠(例如:__test)来标识,
    发表于 02-13 16:49 1464次阅读

    使用Python实现水质量接口调用的代码实例免费下载

    本文档的主要内容详细介绍的是使用Python实现水质量接口调用的代码实例免费下载
    发表于 03-10 16:42 10次下载

    90条关于写Python 程序的建议

    自己写 Python 也有四五年了,一直是用自己的“强迫症”在维持自己代码质量。都有去看Google的Python代码规范,对这几年的工作
    的头像 发表于 05-31 10:12 1239次阅读

    python变量的作用域

    python变量的作用域 1. 作用域 Python的作用域可以分为四种: L (Local) 局部作用域 E (Enclosing) 闭包函数外的函数中 G (Global) 全局作用
    的头像 发表于 03-03 16:50 1263次阅读

    Python-无处不在的变量

    Python中,每个变量在使用前都必须赋值,变量赋值以后,该变量才会被创建
    的头像 发表于 02-16 14:51 416次阅读

    浅析python变量类型

    python不需要事先声明变量python变量类型是在运行过程中自动决定的,不需要代码声明类型。
    的头像 发表于 03-10 10:11 600次阅读
    浅析<b class='flag-5'>python</b>的<b class='flag-5'>变量</b>类型

    如何配置Python环境变量

    配置Python环境变量是在安装Python解释器后的一项重要步骤,它允许您在任何位置都可以通过命令行或脚本运行Python解释器,使Python
    的头像 发表于 04-14 12:16 2w次阅读

    python循环创建变量并赋值

    循环是Python编程中非常重要的一个概念,它可以让我们轻松地重复执行某些代码块,从而简化编程过程并提高代码的效率。在循环中,我们经常需要创建变量并赋值,这是非常常见的操作。接下来,我
    的头像 发表于 11-23 14:51 655次阅读

    python变量命名规则

    的规则和约定。本文将详尽、详实、细致地探讨Python变量的命名规则,帮助读者了解如何正确命名变量并在编程中遵循最佳实践。 一、变量命名规则的重要性 合适的
    的头像 发表于 11-23 15:44 759次阅读

    python软件怎么运行代码

    理解的机器代码。 在本文中,我们将详细介绍如何运行Python代码。我们将探讨以下几个方面:安装Python,设置环境变量,选择一个集成开发
    的头像 发表于 11-28 16:02 562次阅读