Python中优雅使用assert断言的方法实例

目录
  • 什么是 assert 断言
  • 断言和异常的使用场景
  • 使用断言的几个原则
  • 建议不使用断言的情况:
  • 总结

什么是 assert 断言

Assert statements are a convenient way to insert debugging assertions into a program

断言声明是用于程序调试的一个便捷方式。断言可以看做是一个 debug 工具,Python 的实现也符合这个设计哲学,在 Python 中 assert 语句的执行是依赖于__debug__这个内置变量的,其默认值为True。当__debug__为True时,assert 语句才会被执行。

对于一般的声明,assert expression 等价于

if __debug__:
    if not expression: raise AssertionError

assert 可以同时声明两个 expression,例如 assert expression1, expression2 等价于

if __debug__:
    if not expression1: raise AssertionError(expression2)

如果执行脚本文件时加上-O参数, __debug__则为False

举一个例子,假设我们有一个脚本 testAssert.py,内容为:

print(__debug__)
assert 1 > 2

当使用python assert.py运行时,__debug__会输出 True,assert 1 > 2 语句会抛出 AssertionError 异常。

当使用python -O assert.py运行时,__debug__会输出 False,assert 1 > 2 语句由于没有执行不会报任何异常。

断言和异常的使用场景

先说结论:

检查先验条件使用断言,检查后验条件使用异常

举个例子来说明一下,在开发中我们经常会遇到读取本地文件的场景。我们定义一个 read_file 方法。

def read_file(path):
    assert isinstance(file_path, str)
    ...

read_file 函数要求在开始执行的时候满足一定条件:file_path 必须是 str 类型,这个条件就是先验条件,如果不满足,就不能调用这个函数,如果真的出现了不满足条件的情况,证明代码中出现了 bug,这时候我们就可以使用 assert 语句来对 file_path 的类型进行推断,提醒程序员修改代码,也可以使用 if...raise...语句来实现 assert,但是要繁琐很多。在很多优秀的 Python 项目中都会看到使用 assert 进行先验判断的情况,平时可以多多留意。

read_file 函数在被调用执行后,依然需要满足一定条件,比如 file_path 所指定的文件需要是存在的,并且当前用户有权限读取该文件,这些条件称为后验条件,对于后验条件的检查,我们需要使用异常来处理。

def read_file(file_path):
    assert isinstance(file_path, str)
    if not check_exist(file_path):
        raise FileNotFoundError()
    if not has_privilege(file_path):
        raise PermissionError()

文件不存在和没有权限,这两种情况并不属于代码 bug,是代码逻辑的一部分,上层代码捕获异常后可能会执行其他逻辑,因此我们不能接受这部分代码在生产环境中被忽略,这属于后验条件。并且,相比于 assert 语句只能抛出 AssertionError,使用异常可以抛出更详细的错误,方便上层代码针对不同错误执行不同的逻辑。

使用断言的几个原则

  1. 使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。
  2. 使用断言对函数的参数进行确认。
  3. 在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查。
  4. 一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。

断言也可以用于代码测试,用作一个做事毛手毛脚的开发人员的单元测试,只要能你接受当使用-O标志时这个测试什么都不做。我有时也会在代码中用"assert Fasle"来对还没有实现的分支作标记,当然我希望他们失败。如果稍微更细节一些,或许触发NotImplementedError是更好的选择

另一个断言用得好的地方就是检查程序中的不变量。一个不变量是一些你能相信为真的条件,除非一个缺陷导致它变成假。如果有一个缺陷,越早发现越好,因此我们需要对其进行测试,但我们不想因为这些测试而影响代码执行速度。因此采用断言,它能在开发时生效而在产品中失效。

断言也是一个很好的检查点注释。为了替代如下注释:

#当我们执行到这里,我们知道n>2 

#你可以确保在运行时用以下断言:

assert n > 2

建议不使用断言的情况:

  • 不要用于测试用户提供的数据,或者那些需要在所有情况下需要改变检查的地方
  • 不要用于检查你认为在通常使用中可能失败的地方。断言用于非常特别的失败条件。你的用户绝不看到一个AssertionError,如果看到了,那就是个必须修复的缺陷。
  • 特别地不要因为断言只是比一个明确的测试加一个触发异常矮小而使用它。断言不是懒惰的代码编写者的捷径。
  • 不要将断言用于公共函数库输入参数的检查,因为你不能控制调用者,并且不能保证它不破坏函数的合约。
  • 不要将断言用于你期望修改的任何错误。换句话,你没有任何理由在产品代码捕获一个AssertionError异常。
  • 不要太多使用断言,它们使代码变得晦涩难懂。

总结

到此这篇关于Python中优雅使用assert断言的文章就介绍到这了,更多相关Python优雅使用assert断言内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python断言assert的用法代码解析

    在开发一个程序时候,与其让它运行时崩溃,不如在它出现错误条件时就崩溃(返回错误).这时候断言assert 就显得非常有用. python assert断言是声明布尔值必须为真的判定,如果发生异常就说明表达式为假. 可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常. assert的语法格式: assert expression 它的等价语句为: if not expression: raise AssertionError 这段代码用来检测数据类型

  • Python3 assert断言实现原理解析

    语法格式如下: assert expression 等价于: if not expression: raise AssertionError assert 后面也可以紧跟参数: assert expression [, arguments] 等价于: if not expression: raise AssertionError(arguments) 以下为 assert 使用实例: >>> assert True # 条件为 true 正常执行 >>> assert

  • python3 assert 断言的使用详解 (区别于python2)

    python3 和python以前的版本有点不同 如果你断言的 语句正确 则什么反应都没有 但是如果你出错之后 就会报出 AssertionError 并且错误可以自己填写 格式 : assert+空格+要判断语句+双引号"报错语句" 例子: 出错时候 assert 1>5, "chucuo" 输出值为: --------------------------------------------------------------------------- As

  • Python中断言Assertion的一些改进方案

    Python Assert 为何不尽如人意? Python中的断言用起来非常简单,你可以在assert后面跟上任意判断条件,如果断言失败则会抛出异常. >>> assert 1 + 1 == 2 >>> assert isinstance('Hello', str) >>> assert isinstance('Hello', int) Traceback (most recent call last): File "<input>

  • Python中优雅使用assert断言的方法实例

    目录 什么是 assert 断言 断言和异常的使用场景 使用断言的几个原则 建议不使用断言的情况: 总结 什么是 assert 断言 Assert statements are a convenient way to insert debugging assertions into a program 断言声明是用于程序调试的一个便捷方式.断言可以看做是一个 debug 工具,Python 的实现也符合这个设计哲学,在 Python 中 assert 语句的执行是依赖于__debug__这个内置

  • Python中优雅处理JSON文件的方法实例

    目录 1. 引言 2. 什么是JSON文件? 3. 使用Python处理JSON文件 3.1. 将JSON文件读取为字典类型 3.2. 将JSON文件读取为Pandas类型 3.3. 使用Pandas读取嵌套JSON类型 3.4. 访问特定位置的数据 3.5. 导出JSON 3.6. 格式化输出 3.7. 输出字段排序 4.总结 5.参考 1. 引言 在本文中,我们将学习如何使用Python读取.解析和编写JSON文件. 我们将讨论如何最好地处理简单的JSON文件以及嵌套的JSON文件,当然我们

  • 在vue项目中优雅的使用SVG的方法实例详解

    1.基础介绍 本文旨在介绍如何在项目中配置和方便的使用svg图标. 本文以vue项目为例,当然在react中的使用原理基本相似. svg图标可以直接通过img标签来使用,也可当做icon来使用. 本文是参考了鑫旭大佬的文章:SVG Sprite技术介绍. 2.配置 安装svg-sprite-loader.通过vue-cli脚手架创建的项目默认情况下会使用 url-loader 对svg进行处理,所以需要处理下: { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, l

  • python生产环境禁用assert断言的方法

    目录 1. 背景 2.解决方案 2.1 禁用assert的策略 2.2 禁用的原理 3. 实施禁用策略 3.1 启动命令行的参数中,添加-O 3.2 设置PYTHONOPTIMIZE环境变量 4 使用断言的坑 1. 背景 在潜意识中, assert 是应用在unittest或pytest环境中, 不能应用到业务代码中, 因为断言会导致运行中断,对业务有损,并且消耗内存, 影响性能. 但不可否认, 使用断言非常方便调试代码 通过研读assert的文档, 发现断言是可以被关闭的,特此记录下 详细的介

  • python中pygame针对游戏窗口的显示方法实例分析(附源码)

    本文实例讲述了python中pygame针对游戏窗口的显示方法.分享给大家供大家参考,具体如下: 在这篇教程中,我将给出一个demo演示: 当我们按下键盘的'f'键的时候,演示的窗口会切换到全屏显示和默认显示两种显示模式 并且在后台我们可以看到相关的信息输出: 上面给出了一个简单的例子,当然在pygame的官方文档中有对显示策略的更权威的说明: http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode ''' pyga

  • Python中删除文件的几种方法实例

    前言 很多时候开发者需要删除文件.可能是他错误地创建了文件,或者不再需要该文件.无论出于何种原因,都有一些方法可以通过Python来删除文件,而无需手动查找文件并通过UI交互来进行删除操作. 使用Python删除文件有多种方法,但是最好的方法如下: os.remove()删除文件 os.unlink()删除文件.它是remove()方法的Unix名称. shutil.rmtree()删除目录及其下面所有内容. pathlib.Path.unlink()在Python 3.4及更高版本中用来删除单

  • 在python中创建表格的两种方法实例

    目录 日常拉呱: 创建表格一般有两种方法: 一:通过导入xlwt创建 二:通过导入csv库来创建 1.写入数据 2.读取数据 总结 日常拉呱: 最近在学习爬虫模拟登陆各个软件,老师留有作业,模拟登录京东并爬取系列物品,可惜我还是个小白菜鸟,还是处于迷迷糊糊的状态,只能先了解一下边缘知识.爬取完数据,你是否在纠结这些数据放在哪呢?建一个表格或许会帮助到你! 创建表格一般有两种方法: 一:通过导入xlwt来创建,这种方法我比较喜欢,因为它够直观够容易理解,但是相对而言比较麻烦. 二:通过导入csv库

  • python中统计相同字符的个数方法实例

    目录 输入描述: 输出描述: 知识点: 1.Python 字符串中strip()方法 2.Python 字符串中split()方法 3.Python 字符串中lower()方法 补充:python统计两个字符串从首字符开始最大连续相同的字符数 总结 描述 写出一个程序,接受一个由字母.数字和空格组成的字符串,和一个字母,然后输出输入字符串中该字母的出现次数.不区分大小写,字符串长度小于500. 输入描述: 第一行输入一个由字母和数字以及空格组成的字符串,第二行输入一个字母. 输出描述: 输出输入

  • Vue后台中优雅书写状态标签的方法实例

    目录 前言 优化 二次封装 el-tag 组件 使用 总结 前言 在后台系统开发中,对于列表,常常有一些状态字段的展示,比如审核状态.退货申请状态等等,并且往往伴随有状态筛选的列表查询条件,同时状态显示对应不同颜色,在写代码时有些人往往是这么做的: <template> <el-form :model="query"> <el-form-item label="审批状态" prop="status"> <

  • python中matplotlib调整图例位置的方法实例

    目录 前言 1.loc=‘String or Number’ 2.bbox_to_anchor=(num1, num2) 3.举个栗子: 总结 前言 matplotlib画图例默认的位置是在图中的各个角落,但有时图例位置会遮挡住图像而不符合我们的需求,需要对图例位置进行调整.代码如下: plt.legend(loc=‘String or Number’, bbox_to_anchor=(num1, num2)) 1.loc=‘String or Number’ 这个参数来定位图例的大概位置,st

随机推荐