Python3.8中使用f-strings调试


Posted in Python onMay 22, 2019

前言

我日常开发大概有98%的情况下会使用print来调试(别说pdb之类的, 根本不实用),通过在合适的位置插入print语句打印出要跟踪的表达式或者变量的值来确认问题。f-string让格式化这件事变得美观简单,但是依然对调试毫无帮助。

我举个例子:

s = 'A string'
value = 123

如果你想看运行时s和value的值分别是多少(PS: 这里演示的是常量,在实际代码执行中可能他们是表达式或者函数调用计算出来的,那时它们就是动态的了),可以在代码中加一行print打印一下它们:

s = 'A string'
value = 123
print(s, value) # 新插入的行

这样就能通过日志或者终端知道s和value是什么了。不过,这样做的问题是,通过输出对应s和value是不明确的,你需要非常清晰的了解代码逻辑;如果代码中有多个print,每个print都是2个参数,就麻烦了:

s = 'A string'
value = 123
print(s, value)
o = 'Other String'
rv = 234
print(o, rv) # 另外一个print

你还得用某种方法区分他们都是从哪行打印出来的:

s = 'A string'
value = 123
print(s, value, 'S')
o = 'Other String'
rv = 234
print(o, rv, 'Other')

这是我常用的方案,多加一个参数,通过第三项帮你确认分别是哪行打印出来的。

好的写法需要明确你要跟踪的变量和值的对应关系。可以这样写:

>>> print(f's={s!r}, value={value}')
s='A string', value=123
>>> print(f'o={o!r}, rv={rv}')
o='Other String', rv=234

大括号里面的除了有变量,后面还加个 !r ,它是一个转换标志(conversion flag),在过去的format格式化方法中也有。一共有三种转换标志,另外2个分别是 !a 和 !s ,我们感受一下:

>>> '{!a}'.format('哈哈') # 相当于 ascii('哈哈')
"'\\u54c8\\u54c8'"
>>> '{!s}'.format('哈哈') # 相当于 str('哈哈')
'哈哈'
>>> '{!r}'.format('哈哈') # 相当于 repr('哈哈')
"'哈哈'"

上面的例子中, {s!r} 就是对变量s执行 str(s) ,不用(不应该)这样写:

>>> print(f's={s}')
s=A string # 注意,没有引号,空格把值分开了,有多个值的话就不容易辨识
>>> print(f's="{s}"') # 不用`!r`需要手动加引号
s="A string"

不管怎么说,这样其实已经算不错的了,虽然当要打印的变量比较多的时候print语句非常长...

Python 3.8中f-strings的'='

这个功能还是看PyCON2019的闪电演讲看到的,f-strings的作者Eric V. Smith接受了Larry Hastings的意见实现了f-string的调试功能。本来是想另外一个转换标识 !d ,效果大概是这样:

value = 10
s = 'a string!'
print(f'{value!d}')
print(f'next: {value+1!d}')
print(f'{s!d}')
print(f'{s!d:*^20}')
print(f'*{value!d:^20}*')
# 输出
value=10
next: value+1=11
s='a string!'
'****s="A string"****'
*   value=10   *

也就是说,f-strings自动添加 变量名 + = ,而且支持补齐空位还能做表达式求值,如上例, {value+1!d} 表示计算 value+1 再打印出来。

不过后来作者和Guido讨论,改用了更灵活的 = 。现在已经合并到Python3.8,我们可以真实的试用了:

❯ ./python.exe
Python 3.8.0a4+ (heads/master:2725cb01d7, May 22 2019, 10:29:22)
...
>>> print(f'{s=}, {value=}')
s='A string', value=123
>>> print(f'{o=}, {rv=}')
o='Other String', rv=234
>>> print(f'{value / 3 + 15=}')
value / 3 + 15=56.0
>>> print(f'{s=:*^20}')
s=******A string******
>>> print(f'*{s=:^20}*')
*s=   A string   *

为啥我说用 = 更灵活呢,再看几个混合转换标识的例子:

>>> x = '哈哈'
>>> f'{x=}'
"x='哈哈'"
>>> f'{x=!s}'
'x=哈哈'
>>> f'{x=!r}'
"x='哈哈'"
>>> f'{x=!a}'
"x='\\u54c8\\u54c8'"
>>> f'{x=!s:^20}'
'x=     哈哈     '

就是说,DEBUG模式可以和转换标识一起用!

学到了吧?开始期待Python3.8了~

PS: 如果你看了PyCON的那个「Easier debugging with f-strings」的演讲(延伸阅读链接2),其中还是说用 !d ,其实演讲后第二天就改成了 = 了,要注意哈~

总结

以上所述是小编给大家介绍的Python3.8中使用f-strings调试,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
Tornado协程在python2.7如何返回值(实现方法)
Jun 22 Python
python实现TF-IDF算法解析
Jan 02 Python
对python-3-print重定向输出的几种方法总结
May 11 Python
Python 使用PIL中的resize进行缩放的实例讲解
Aug 03 Python
使用python生成杨辉三角形的示例代码
Aug 29 Python
python读取TXT每行,并存到LIST中的方法
Oct 26 Python
Windows下Python3.6安装第三方模块的方法
Nov 22 Python
python hbase读取数据发送kafka的方法
Dec 27 Python
Python3利用print输出带颜色的彩色字体示例代码
Apr 08 Python
Python学习之路安装pycharm的教程详解
Jun 17 Python
pytorch查看模型weight与grad方式
Jun 24 Python
用python实现前向分词最大匹配算法的示例代码
Aug 06 Python
总结Python图形用户界面和游戏开发知识点
May 22 #Python
Python闭包和装饰器用法实例详解
May 22 #Python
Python进程间通信Queue消息队列用法分析
May 22 #Python
将python文件打包成EXE应用程序的方法
May 22 #Python
Python多线程threading模块用法实例分析
May 22 #Python
Python3之手动创建迭代器的实例代码
May 22 #Python
PyTorch搭建一维线性回归模型(二)
May 22 #Python
You might like
PHP版国家代码、缩写查询函数代码
2011/08/14 PHP
PHP新特性之字节码缓存和内置服务器
2017/08/11 PHP
jquery+json实现的搜索加分页效果
2010/03/31 Javascript
浅析JS刷新框架中的其他页面 && JS刷新窗口方法汇总
2013/07/08 Javascript
单元选择合并变色示例代码
2014/05/26 Javascript
JavaScript中的console.log()函数详细介绍
2014/12/29 Javascript
javascript+html5实现仿flash滚动播放图片的方法
2015/04/27 Javascript
微信js-sdk地理位置接口用法示例
2016/10/12 Javascript
javascript显示系统当前时间代码
2016/12/29 Javascript
微信小程序 页面跳转传递值几种方法详解
2017/01/12 Javascript
Base64(二进制)图片编码解析及在各种浏览器的兼容性处理
2017/02/09 Javascript
jQuery ajax仿Google自动提示SearchSuggess功能示例
2019/03/28 jQuery
微信小程序 自定义复选框实现代码实例
2019/09/04 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
2020/02/14 Javascript
[01:25:38]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第一场 1月19日
2021/03/11 DOTA
Python Tkinter GUI编程入门介绍
2015/03/10 Python
Python 自动刷博客浏览量实例代码
2017/06/14 Python
python学习笔记之列表(list)与元组(tuple)详解
2017/11/23 Python
matplotlib作图添加表格实例代码
2018/01/23 Python
python构建指数平滑预测模型示例
2019/11/21 Python
Python连接SQLite数据库并进行增册改查操作方法详解
2020/02/18 Python
快速创建python 虚拟环境
2020/11/28 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
2020/12/08 Python
CSS3 :default伪类选择器使用简介
2018/03/15 HTML / CSS
德国狗狗用品在线商店:Schecker
2017/03/17 全球购物
荷兰牛仔裤网上商店:Jeans Centre
2018/04/03 全球购物
JoJo Maman Bébé爱尔兰官网:英国最受欢迎的精品母婴品牌
2020/12/20 全球购物
Java文件和目录(IO)操作
2014/08/26 面试题
毕业自我评价
2014/02/05 职场文书
工商行政管理专业求职书
2014/05/23 职场文书
国家领导干部党的群众路线教育实践活动批评与自我批评材料
2014/09/23 职场文书
费用申请报告范文
2015/05/15 职场文书
《称赞》教学反思
2016/02/17 职场文书
一文帮你理解PReact10.5.13源码
2021/04/03 Javascript
用python基于appium模块开发一个自动收取能量的小助手
2021/09/25 Python
画错魏国疆域啦!《派对咖孔明》动画因作画失误于官网致歉
2022/04/07 日漫