1. 使用 assert 加一层保险

断言是为了告诉开发人员程序中发生了不可恢复的错误,对于可以预料的错误(如文件不存在),用户可以予以纠正或重试,断言并不是为此而生的。

断言用于程序内部自检,如声明一些代码中不可能出现的条件,如果触发了某个条件,即意味着程序中存在着相应的bug。

Python断言是一种调试辅助功能不是用来处理运行时错误的机制

语法:assert expression1 [, expression2]

expresssion1 是要判断的表达式,expression2 是可选的,用于返回错误信息

【注意】

  • 不要使用断言验证数据,因为有可能程序被禁用断言
  • 不要写出永远不会失败的断言

2. 巧妙放置逗号

举个例子就明白了

names = ['Alice',
'Bob',
'Alex',
]

这样可以删除任意一行元素,或者随意添加元素也方便,不用管逗号问题。

3. 上下文管理器和 with 语句

with 语句有助于简化一些通用资源管理模式,抽象出其中的功能,将其分解并重用。

with open("hello.txt", 'w') as f:
f.write('hello world!')

避免忘记手动关闭 IO 流

这样代码既好懂,又简洁,我们可以在自定义对象中支持 with

只要实现所谓的上下文管理器,就可以在自定义的类和函数中获得相同的功能。

简单点,如果想将一个对象作为上下文管理器,需要做的就是向其中添加__enter____exit__方法。下面以open()为例,简单手动实现一个上下文管理器。

class ManageFile(object):
def __init__(self, name):
self.name = name def __enter__(self):
self.file = open(self.name, 'w')
return self.file def __exit__(self, exc_type, exc_val. exc_tb):
if self.file:
self.file.close()

至此,我们可以这样调用:

with ManageFile('hello.txt') as f:
f.write('hello world!')
f.write('bye now!')

当流程进入with语句上下文时,Python会调用__enter__获取资源,离开with上下文时,Python会调用__exit__释放资源。

上面的是原始的套路,实际使用当然有简化版。标准库中的contextlib模块在上下文管理器基本协议的基础上提供了更多抽象。如果遇到的情形正好能用到contextlib提供而功能,那么可以节省很多精力。

【例1】

from contextlib import contextmanager

@contextmanager
def make_open_context(filename, mode):
fp = open(filename, mode)
try:
yield fp
finally:
fp.close() with make_open_context('/tmp/a.txt', 'a') as file_obj:
file_obj.write("hello carson666")

【例2】

# _*_ coding:utf-8 _*_
from contextlib import contextmanager """
contextmanager给了我们一个机会,即将原来不是上下文管理器的类变成了一个
上下文管理器,例如这里的MyResource类
""" class MyResource:
def query(self):
print("query data") @contextmanager
def make_myresource():
print("connect to resource")
yield MyResource()
print("connect to resource") with make_myresource() as r:
r.query()

输出:

connect to resource
query data
connect to resource

【例3】

# _*_ coding:utf-8 _*_

from contextlib import contextmanager

@contextmanager
def book_mark():
print('《', end="")
yield
print('》', end="") with book_mark():
# 核心代码
print('且将生活一饮而尽', end="")

输出:

《且将生活一饮而尽》

以上就是对类和函数实现上下文管理的方法

4. 下划线、双下划线及其他

4.1 前置单下划线:_var

当涉及变量名和方法时,前置单下划线只有约定含义,并不强制,只是提醒使用者不要在外部调用。

Python中如果使用通配符*导入一个模块所有包,此时不会导入带前置单下划线的名称(除非__all__列表定义覆盖)

顺带说一下,应避免使用通配符导入,疑问这样就不清楚你在该文件使用了什么名称,常规导入是可以将前置单下划线的名称引入的。

4.2 后置单下划线:var_

有时,某个变量最适合额名称已被Python中关键字占用,在这种情况下,可以追加一个下划线来绕过命名冲突。

PEP8已定义并解释了这个约定

如果你使用过numpy这些科学计算库,你会发现里面也有后置单下划线的函数,这种函数一般代表的是原位操作,去掉后置单下划线则是通常操作,返回的是clone后的对象。

4.3 前置双下划线:__var

双下划线前缀会让Python解释器重写属性名称,以避免子类中额命名冲突。下面来试验一下:

class Test(object):
def __init__(self):
self.foo = 11
self._bar = 22
self.__baz = 33 t = Test()
print(dir(t))

输出:

['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__init_subclass__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', '_bar', 'foo']

你会发现,前两个变量都有,而第三个变量则没有了,它被名称改写为_Test__baz了,是为了防止子类覆盖这些变量。

名称改写可用于属性和方法名,并且,名称改写并不与类属性绑定。

4.4 前后双下划线:__var__

双下划线的方法通常被称为魔法方法,重写这类方法时,一般是为了实现某种Python语言特性。

例如前面遇到的上下文管理器的实现。

4.5 单下划线:_

一般,若果你的函数返回值有多个,而你并不是所有都需要,那么你对不需要的返回值可以用_接收。

5. 格式化字符串

具体的使用规则不再赘述,这里主要谈谈如何选用Python的四种格式化字符串:

如果格式化字符串是用户提供的,使用模板字符串来避免安全问题。如果不是,再考虑Python版本:Python 3.6+使用字符串字面值插值,老版本则使用“新式”字符串格式化。

『Python』整洁之道的更多相关文章

  1. Python代码整洁之道(一)

    很多新手在开始学一门新的语言的时候,往往会忽视一些不应该忽视的细节,比如变量命名和函数命名以及注释等一些内容的规范性,久而久之养成了一种习惯.对此呢,我特意收集了一些适合所有学习 Python 的人, ...

  2. 『Python』__getattr__()特殊方法

    self的认识 & __getattr__()特殊方法 将字典调用方式改为通过属性查询的一个小class, class Dict(dict): def __init__(self, **kw) ...

  3. 『Python』 ThreadPool 线程池模板

    Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...

  4. 『Python』Python 调用 ZoomEye API 批量获取目标网站IP

    #### 20160712 更新 原API的访问方式是以 HTTP 的方式访问的,根据官网最新文档,现在已经修改成 HTTPS 方式,测试可以正常使用API了. 0x 00 前言 ZoomEye 的 ...

  5. 『Python』为什么调用函数会令引用计数+2

    一.问题描述 Python中的垃圾回收是以引用计数为主,分代收集为辅,引用计数的缺陷是循环引用的问题.在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存. sys.g ...

  6. 『Python』库安装

    1.安装指定版本的tensorflow 虽然官网有4种安装方式,并且推荐用anaconda的方式,但是有时候我们需要指定版本的tensorflow,而pip可以做到. 比如我装的是anaconda3. ...

  7. 『Python』装饰器

    一.参考 作者:zhijun liu 链接:https://www.zhihu.com/question/26930016/answer/99243411 来源:知乎 建议大家去原答案浏览 二.装饰器 ...

  8. 『Python』多进程处理

    尝试学习python的多进程模组,对比多线程,大概的区别在: 1.多进程的处理速度更快 2.多进程的各个子进程之间交换数据很不方便 多进程调用方式 进程基本使用multicore() 进程池优化进程的 ...

  9. 『Python』内存分析_list和array

    零.预备知识 在Python中,列表是一个动态的指针数组,而array模块所提供的array对象则是保存相同类型的数值的动态数组.由于array直接保存值,因此它所使用的内存比列表少.列表和array ...

随机推荐

  1. 题解—P2511 [HAOI2008]木棍分割

    这道题第一眼直接一个二分板子把第一问解决掉,然后主要是统计方案. 其实这个方程还不算难推,只要推出来朴素 \(dp\) ,之后的一步一步也很顺理成章,所以这种题主要看能不能静下心来慢慢做. solut ...

  2. mysql删除大表更快的办法

    实现:巧用LINK(硬链接),原理:linux文件系统中硬链接相当于文件的入口,记录着ionde的信息.一个文件存在多个硬连接时,删除一个硬链接不会真正的删除ionde(存储文件的数据) # 创建硬链 ...

  3. 15.SpringMVC之异步请求

    SpringMVC中异步请求相关组件 SpringMVC在此基础上对异步请求进行了封装.提供了AsyncWebRequest类型的request,并提供了处理异步请求的管理器WebAsyncManag ...

  4. dubbo暴露原理及引用过程

    服务暴露 服务引用:

  5. Consul 入门-初识

    背景 现状:单体架构逐渐被微服务架构所替代,原本两个功能模被拆分成了两个服务.原本两个模块块间的通信只需要函数调用就能够实现,现在却做不到了,因为它们不在同一个进程中,甚至两个服务都可能部署到不同的机 ...

  6. 收下这7款插件,让你在使用 Vite 的时候如虎添翼

    相信已经有不少小伙伴已经开始用 Vue3 做开发了,也一定使用上 Vite 了,而我今天要介绍的这几款插件,能让你在使用 Vite 做开发时如虎添翼. vite-plugin-restart 通过监听 ...

  7. Linux·命令收藏

    时间:2018-11-20 记录:byzqy 标题:Linux命令大全(手册) 地址:http://man.linuxde.net/ 标题:Linux script命令 -- 终端里的记录器 地址:h ...

  8. js调试之firbug

    说下几种方法吧: 1.用alert 这个最最直观 把你想要的内容弹出来给你看,但是要看哪里 就要在哪里加,比较麻烦 2.用firefox 或者chrome浏览器 里面有debug工具的 3.如果想用i ...

  9. LeetCode《买卖股票的最佳时机》系列题目,最详解

    目录 说在前面 引例:只能交易一次 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 无限制买卖 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 交易 2 次,最大利润? 一.动态数 ...

  10. LeetCode通关:连刷三十九道二叉树,刷疯了!

    分门别类刷算法,坚持,进步! 刷题路线参考:https://github.com/youngyangyang04/leetcode-master 大家好,我是拿输出博客来督促自己刷题的老三,这一节我们 ...