Python变量与注释高级用法

1.概述

好的变量和注释并非为计算机而写,而是为每个阅读代码的人而写。变量与注释是表达作者思想的基础,他们对代码质量的贡献母庸质疑。

2.变量

2.1.变量解包

1.什么是变量解包

把一个可迭代对象的所有成员,一次性的赋值给多个变量的过程就是变量解包。

2.变量解包语法

# 变量解包
username = ['zhangsan', '18']
name, age = username
print('name:{}, age:{} '.format(name, age))# 嵌套类型变量解包
username = [1, ['zhangsan', 18]]
number, (name, age) = username
print('number:{}, name:{}, age:{}'.format(number, name, age))# 匹配模式解包
data = ['zhangsan', 'banana', 'apple', 'orange', 18]
name, *fruits, score = data
print('name:{}, fruits:{}, score:{}'.format(name, fruits, score))# 切片解包
data = ['zhangsan', 'banana', 'apple', 'orange', 18]
name, fruits, score = data[0], data[1:-1], data[-1]
print('name:{}, fruits:{}, score:{}'.format(name, fruits, score))# 变量解包用到for循环
for name, age in [('zhangsan', 15), ('lisi', 18)]:print('name:{}, age:{}'.format(name, age))# 单下划线变量名
username = ['zhangsan', 19]
name, _ = username
print(name, _)

2.2.给变量注明类型

1.变量注明类型介绍

python给变量注明类型,与java变量类型不同,python的变量类型只是一种提示功能,不提供任何校验功能。
因此传入的变量类型与校验类型不一致也不会报错。

变量注明类型语法非常简单,在变量名称后面用冒号分隔表名类型即可。

2.变量注明类型示例

# list表示参数为列表类型,int表示里面的成员是整形
def remove_invalid(item: list[int]):print(item)# 传入符合变量类型参数
remove_invalid([1, 2, 3])
# 传入不符合变量类型参数,不影响函数执行结果。
remove_invalid(1)# 类型注解使用demo
class Duck:def __init__(self, color:str):self.color = color# 为quack方法注明返回值类型为Nonedef quack(self) -> None:print(f"Hi, I'm a {self.color} duck")# -> List[Duck]:用typing模块的List对象为函数返回值标注具体类型
def create_random_ducks(number:int) -> List[Duck]:# 为变量加上类型声明ducks: List[Duck] = []for _ in number:color = random.choice(['yellow', 'white', 'gray'])ducks.append(Duck(color=color))return ducksducks = create_random_ducks((1,2,3))
for duck in ducks:duck.quack()

2.3.变量命名原则

给变量起名主要有两种流派:一是通过大小写界定单词的驼峰命名,例如Java语言。二是通过下划线连接的蛇形命名,例如python语言。

  • 遵循PEP8原则
  • 描述性要强
  • 长度尽量短
  • 变量注明类型
  • 超短命名

1.遵循PEP8原则

PEP8原名《Python Enhacement Proposal #8》译为《8 号 Python 增强规范》为代码编写风格提供了指南,变量命名部分规范如下。

  • 普通变量,使用蛇形命名法,比如max_value
  • 常量,采用全部大写字母,使用下划线连接,比如 MAX_VALUE
  • 仅内部使用变量,在变量前增加下划线前缀,比如 _local_var
  • 变量名称与python关键字冲突时,在变量末尾追加下划线,比如 class_

2.描述性要强

写作过程中一项重要的工作就是为句子斟酌恰当的词语,不同的词语描述性的强弱是不同的。比如”冬天傲骨的梅花“ 就比 ”花“ 描述性要强。为变量命名和词语一样,同样有描述性强弱之分。
下面是描述性强弱不同的变量,对比可以感受到描述性强的变量名称使代码更易读。

# 描述性弱的变量名称:看不出它在描述什么
vlaue = process(s.strip())# 描述性强的变量名称:从用户输入参数中解析出用户名称,并剔除参数中的空格。
username = extract_username(input_string.strip())

3.长度尽量短

假如一个特别长的重复出现,读者不会觉得它精确,反而是啰嗦难读。在保证描述性清晰前提下,尽量让名字简短易读,通常控制在4个单词内。

4.变量注明类型

虽然python的变量不需要声明类型,但是为了提升可读性,我们可以为变量注明类型。
除了为变量注明类型外,还有约定俗称的变量名称与类型建立匹配关系,下面是一些变量名称和类型匹配的例子。

  • 匹配布尔值类型的变量名
变量名 含义 说明
is_superuser 是否是超级用户 is 表示是或不是
has_errors 有没有错 hans 表示有或没有
allow_empty 是否允许空值 allow表示是否允许

5.超短命令

在变量命名中有一类名称比较特别,只有一两个字母,通常他们分为两类,一类是大家约定俗称的短名字,另一类是起别名。

约定俗称常用名称

  • 数组索引三剑客 i、j、k
  • 某个整数 n
  • 某个字符串 s
  • 某个异常 e
  • 文件对象 fp

长名称起别名

is_not_normal as l

3.注释

注释不会影响代码的行为,它会影响代码的可读性。

3.1.注释类型

python的注释分为两种,一种是代码内注释,一种是函数、类的注释也称为接口注释。

行内注释

# 使用strip()去掉空格的好处:
# 1.数据库保存数据时占用空间更小
# 2.不必因为用户多打了空格而要求用户重新输入。username = extract_username(input_string.strip())

接口注释

class Person:# 使用三个单引号或三个双引号就是接口注释。'''人:param name: 姓名: param age: 年龄: param favrite_color: 最喜欢的颜色'''def __init__(self, name, age, favrite_color):self.name = nameself.age = ageself.favrite_color = color

3.2.错误使用注释案例

1.用注释屏蔽代码

在编程中会用注释屏蔽代码,如果这些代码不需要了可以直接删掉,如果需要用到这些代码可以从Git仓库中找到。临时注释掉的大段代码,对于阅读代码的人来说是一种干扰,没有任何意义。

2.用注释复述代码

# 调用strip()去掉空格
input_string = input_string.strip()

上面这样的注释完全是冗余的,因为读者从代码本身就能读到注释里的信息。好的注释应该是这样

# 如果将带有空格的参数传递到后端处理,可能会造成服务奔溃
# 因此使用strip()去掉收尾空格
input_string = input_string.strip()

注释作为代码之外的说明性文字,应该尽量提供那些读者无法从代码里读出的信息,描述代码为什么要这么做,而不是简单复述代码本身。

除了为什么的解释性注释外,还有一种注释也很常见:指引性注释
这种注释不复述代码,而是简明扼要概括代码功能,起到”代码导读“作用。
指引性注释并不提供代码里读不到东西——假如没有注释,耐心读完所有代码也能知道代码做了什么。指引性注释就是降低代码认知的成本,让我们更容易理解代码的意图。

指引性注释示例

# 初始化访问服务的client对象
token = token_service.get_token()
service_client = ServiceClient(token = token)
service_client.ready()

3.用接口注释阐述函数实现细节

在编写接口注释时,经常会看到下面的情况。

def resize_image(image, size):'''将图片缩放到指定尺寸,并返回新的图片。该函数将使用pilot模块读取文件对象,然后调用.resize()方法将其缩放到指定尺寸。但由于pilot模块自身限制,这个函数不能很好的处理过大文件,当文件超过5MB时,resize()方法的性能就会急剧下降,因此超过5MB文件,使用resize_big_image()替代,后者基于Pillow模块开发,很好的解决了内存分配问题,确保更好的性能。:param image: 图片文件对象:param size: 包含宽高的元组(width, height):return: 新图片对象'''

这段接口注释最主要的问题在于过多的阐述了函数实现的细节,提供了太多其他人并不关系的内容。

接口注释主要是给函数或类的使用者看的,它存在的最主要价值,是让人们不用逐行阅读函数代码,就能从注释中知道该如何使用这个函数,以及使用时需要注意事项

在编写接口注释时我们应该站在函数设计者的角度,着重描述函数的功能,参数等。而函数自身实现细节无需放在接口注释中,放到函数内部代码注释即可。

下面是改进后的接口注释

def resize_image(image, size):'''将图片缩放到指定尺寸,并返回新的图片。注意:当文件超过5MB时,请使用resize_big_image():param image: 图片文件对象:param size: 包含宽高的元组(width, height):return: 新图片对象'''

4.编程建议

4.1.变量使用建议

1.保持变量一致性

在使用变量时,需要保证他在两个方面的一致性:名字一致性与类型一致性。

  • 名字一致性是指在同一个项目、模块、函数中,对同一类事物称呼不要变来变去。比如用户头像叫做user_avatar_url,那么在其他地方不要把它改成user_profile_url。否则读代码的人不知道这两个变量名称指的是否是同一个东西。
  • 类型一致性是指不要把一个变量重复指向不同类型的值。举个例子:
def():#user 是一个Dict类型user = {'data':['zhangsan','wangwu']}# user 这个名字好用,重复使用它,把它变成Listuser = []

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

定义变量应该把它们放到每段 “各司其职” 的代码头部,缩短变量从初始化到使用的 “距离”。当读者阅读代码时,可以更容易理解代码逻辑,而不是来回翻阅代码查看变量是在什么时候定义的,在什么时候使用的。

3.定义临时变量提升可读性

当代码中遇到复杂的逻辑时,判断条件就会变得复杂,这时候可以采用临时变量简化判断条件的复杂度,提升代码的可阅读性。

举例:定义临时变量提升代码阅读性

# 为所有女性或者级别大于3的活跃用户发放1000个金币
if user.is_active and (user.sex == 'female' or user.level > 3):user.add_coins(1000)# 上面业务逻辑使判断条件变得复杂,阅读起来有些费劲,这时候我们可以把后面复杂的表达式赋值给一个临时变量,代码阅读性就会有所提升,下面是例子。user_is_eligible = user.is_active and (user.sex == 'female' or user.level > 3)
if user_is_eligible:user.add_coins(1000)'''
在新的代码中,“计算用户合规的表达式” 和 “判断合规发送金币的条件分支” 这两段代码不再揉捏在一起,
而是添加了一个可读性强的变量作为缓冲,不论是代码的可读性还是维护性都因为这个变量增强了。
'''

4.同一作用域内不要有太多的变量

函数越长,用到的变量就越多。但是人脑记忆是有限的,太多的变量会使代码变得难读。如果函数内变量太多,通常是函数承担了太多的职责,把复杂的函数拆分为多个小涵数,代码的整体复杂度会降低。

5.能不定义变量就别定义

在编写代码时,我们会下意识的定义很多变量,好为未来调整代码做准备,但是你所想的未来也许永远不会来。
下面是一个定义临时变量过多的例子,我们对它做了优化。

# 定义过多的临时变量会让阅读代码的读者觉得啰嗦,阅读性不好。
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) }

4.2.注释使用建议

1.空行也是一种"注释"

在写代码的时候,我们可以适当地在代码中插入空行,把代码按不同逻辑块分隔开,这样做能有效提升代码的可读性。

2.先写注释,后写代码

在写代码时有一个好习惯值得推荐:先写注释,后写代码。

比如在开发代码过程中写的最多的就是函数,封装业务逻辑也是函数,下面就来聊聊函数开发的好习惯。
每个函数的名称与接口注释,其实是一种比函数内部更为抽象的东西。你需要在函数名和短短几行注释里,把函数内代码所做的事情,高度浓缩的表达清楚。

正因为如此,接口注释其实可以当成一种协助你设计函数的前置工具。这个工具用法很简单:假如你没法通过几行注释把函数的职责描述清楚,那么整个函数的合理性就该打个问号

举例:
你在写一个函数process_user(),编写函数注释时,你发现在写了好几行文字后,仍然没法把函数的职责描述清楚,因为它可以同时完成好多件不同的事情。这时你就该意识到,process_user()函数承担了太多的职责,解决办法就是直接删掉它,设计更多单一职责的子函数来替代。

先写注释的另一个好处是:不会漏掉任何应该写的注释。

为什么大家会漏掉注释?我的一个猜测是:程序员在编写函数时,总是跳过接口注释直接开始写代码。而当写完代码,
实现函数的所有功能后,他就对这个函数失去了兴趣。这是他最不愿意做的事,就是回过头去补写函数的注释,
级别写了也只是草草对付了事。

如果遵守 “先写注释,后写代码” 的习惯,我们就可以完全避免上面的问题。养成这个好习惯 ,其实很简单:在写出一句有说服力的接口注释前,先别写任何函数代码。

Python变量与注释高级用法相关推荐

  1. Python面试常用的高级用法,怎么动态创建类?

    元类是Python当中的 高级用法 ,如果你之前从来没见过这个术语或者是没听说过这个概念,这是非常正常的,因为一方面它的 使用频率不高 ,另外一方面就是它相对 不太容易理解 .以至于很多Python开 ...

  2. python基础和第三方库 笔记(python基础完结包括高级用法,第三方库持续更新中...)

    python基础 注:本笔记面向有一定基础的人 本笔记是本人快速复习python过程中记录的,不适合零基础的人学习python的主工具,可以作为辅工具,本笔记记录了入门阶段常用操作,如有错误的地方,希 ...

  3. Python的 5 种高级用法,效率提升没毛病!

    (给视学算法加星标,提升Python技能) 转自:机器之心(ID:almosthuman2014) 任何编程语言的高级特征通常都是通过大量的使用经验才发现的.比如你在编写一个复杂的项目,并在 stac ...

  4. day1 -- Python变量、注释、格式化输出字符串、input、if、while、for

    1.python变量 不需要声明类型,直接 变量名 = 变量值,如 : name = "hahaha" 2.注释: 单行注释,前面加 #,如  # print(info) 多行注释 ...

  5. python变量定义的规则_Python基础教程(2)Python变量与注释

    一.Python变量定义规则 在Python中定义变量的方式和Shell很像,有以下规则: 1.变量名只能是字母.数字或者下划线的组合,不能有空格或者其他特殊字符,且第一个字符不能是数字 2.使用变量 ...

  6. python的5种高级用法,效率提高没毛病!

    任何编程语言的高级特征通常都是通过大量的使用经验才发现的.比如你在编写一个复杂的项目,并在 stackoverflow 上寻找某个问题的答案.然后你突然发现了一个非常优雅的解决方案,它使用了你从不知道 ...

  7. python sort、sorted 高级用法

    python sort.sorted高级排序技巧 转载原因:学习<机器学习实战>决策树这一章节时,对为了确定叶节点而采用的多数表决法的python程序有些疑惑 故求助度娘,发现了这篇文章, ...

  8. python 变量类型注释_变量类型、命名规则及代码注释

    人类在纸上可以写数字,也可以写文字,用数字来计算,用文字来说话,在人类的意识里你写的东西代表不同的含义!同样,在程序里面我们也按照人的习惯来设计,因此就有了变量类型这种说法!任何语言都会涉及到变量类型 ...

  9. 关于python中def的高级用法,def中套def,python函数装饰器

    Python函数装饰器 装饰器(Decorators)是 Python 的一个重要部分.简单地说:他们是修改其他函数的功能的函数.他们有助于让我们的代码更简短,也更Pythonic(Python范儿) ...

最新文章

  1. JS数据类型与分支结构
  2. 无网络状态下修改计算机ip,电脑突然没有网络的到底是什么原因,查看ip地址...
  3. 图像梯度处理MATLAB代码
  4. Spring Boot 2.3.0——以war方式打包失败[webxml attribute is required]解决方案
  5. mybatis初始化过程
  6. SpringMVC处理静态资源
  7. String 转化 list
  8. request.RequestContextListener
  9. Eclipse导入Android项目的方法(转)
  10. SpringCloud下的springboot工程,访问jsp页面报404问题
  11. RePast J介绍
  12. List转JSON格式方法
  13. java金蝉素数_回文素数 - 寂寞暴走伤的个人空间 - OSCHINA - 中文开源技术交流社区...
  14. 美国亚马逊编辑推荐的一生必读书单100本
  15. python更改文件名
  16. 服务器虚拟机化对应云计算的,服务器虚拟化与云计算
  17. BS1063-基于大数据分析实现个性化音乐在线推荐平台,音乐资源分析平台
  18. 核电站问题 动态规划
  19. React:Redux和Flux
  20. 论文参考文献格式标准

热门文章

  1. Linux 0.00简单多任务内核boot.s超详注释
  2. 《Adobe Photoshop CS5中文版经典教程(全彩版)》—第2课2.6节替换图像中的颜色...
  3. poi读取Excel时日期为数字 的解决方法
  4. 信息资源管理3500字超详细,全网最全笔记!!(第一章 1)
  5. Linux硬盘分区相关命令
  6. 基于计算机视觉的无人驾驶感知系统
  7. 盒模型和开发中常用的布局
  8. slxrom+v.21+原生android+4.2,红米Note4X高通版 魔趣OS 安卓10 MagiskV21版 完美ROOT 纯净完美 原生极简 纯净推荐...
  9. 用VideoView实现播放本地的m3u8
  10. 数据可视化新闻,不一样的新闻报道形式