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 相关文章推荐
Python实现的RSS阅读器实例
Jul 25 Python
Python实现快速排序算法及去重的快速排序的简单示例
Jun 26 Python
Python 装饰器深入理解
Mar 16 Python
python+requests+unittest API接口测试实例(详解)
Jun 10 Python
python去掉空白行的多种实现代码
Mar 19 Python
Python 数据处理库 pandas进阶教程
Apr 21 Python
一看就懂得Python的math模块
Oct 21 Python
Python2和Python3之间的str处理方式导致乱码的讲解
Jan 03 Python
Python多进程fork()函数详解
Feb 22 Python
使用 prometheus python 库编写自定义指标的方法(完整代码)
Jun 29 Python
python两种注释用法的示例
Oct 09 Python
使用tkinter实现三子棋游戏
Feb 25 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
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
2007/02/22 PHP
php UTF-8、Unicode和BOM问题
2010/05/18 PHP
微信红包随机生成算法php版
2016/07/21 PHP
PHP中in_array的隐式转换的解决方法
2018/03/06 PHP
document.documentElement的一些使用技巧
2013/04/18 Javascript
Ext修改GridPanel数据和字体颜色、css属性等
2014/06/13 Javascript
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
ionic js 模型 $ionicModal 可以遮住用户主界面的内容框
2016/06/06 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐)
2016/06/23 Javascript
js style.display=block显示布局错乱问题的解决方法
2016/09/21 Javascript
canvas知识总结
2017/01/25 Javascript
JS仿淘宝搜索框用户输入事件的实现
2017/06/19 Javascript
Vue.js自定义事件的表单输入组件方法
2018/03/08 Javascript
JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析
2018/08/25 Javascript
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
2018/09/13 Javascript
electron 如何将任意资源打包的方法步骤
2020/04/16 Javascript
python3.3使用tkinter开发猜数字游戏示例
2014/03/14 Python
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
利用Python脚本在Nginx和uwsgi上部署MoinMoin的教程
2015/05/05 Python
python通过get,post方式发送http请求和接收http响应的方法
2015/05/26 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
2017/09/11 Python
python+pyqt实现右下角弹出框
2017/10/26 Python
python中使用xlrd读excel使用xlwt写excel的实例代码
2018/01/31 Python
python全栈要学什么 python全栈学习路线
2019/06/28 Python
python redis连接 有序集合去重的代码
2019/08/04 Python
PyCharm第一次安装及使用教程
2020/01/08 Python
python模拟实现分发扑克牌
2020/04/22 Python
使用Python+Appuim 清理微信的方法
2021/01/26 Python
英国时尚优质的女装:Hope Fashion
2018/08/14 全球购物
美国亚洲时尚和美容产品的一站式网上商店:Stylevana
2019/09/05 全球购物
墨西哥购物网站:Elektra
2020/01/21 全球购物
师范毕业生求职自荐信
2013/09/25 职场文书
党的群众路线教育实践活动整改落实情况自查报告
2014/10/28 职场文书
敬老院活动感想
2015/08/07 职场文书
学习经验交流会演讲稿
2015/11/02 职场文书
十大公认最好看的动漫:《咒术回战》在榜,《钢之炼金术师》第一
2022/03/18 日漫