Python 3.11新功能:错误信息回溯

news2025/1/12 19:52:30

错误信息回溯

长按关注《Python学研大本营》,加入读者群,分享更多精彩 扫码关注《Python学研大本营》,加入读者群,分享更多精彩

Python 3.11于2022 年 10 月 24 日发布。这个最新版本的 Python 速度更快,对用户更友好。

与每个版本一样,Python 3.11 都进行了许多改进和更改。您可以在文档中看到所有这些的列表。在这里,您将探索最酷、最具影响力的新功能。

在本专题的教程中,您将了解新功能和改进,例如:

  • 更好的错误消息和更多信息的回溯

  • 由于Faster CPython项目付出了巨大的努力,代码执行速度更快

  • 简化使用异步代码的任务和异常组

  • 改进 Python 的静态类型支持的几个新类型特性

  • 本机TOML 支持处理配置文件

如果您想尝试本教程中的任何示例,则需要使用 Python 3.11。Python 3 安装和设置指南(https://realpython.com/installing-python/)以及如何安装 Python 的预发布版本(https://realpython.com/python-pre-release/)引导您完成向系统添加新版本 Python 的几个选项。

除了了解有关该语言的新功能的更多信息外,您还将获得一些关于在升级到新版本之前要考虑什么的建议。下面的链接下载演示 Python 3.11 新功能的代码示例(https://realpython.com/bonus/python-311-examples/)

信息错误回溯

Python 通常被认为是一种很好的初学者编程语言,它具有可读的语法和强大的数据结构。所有人都面临的挑战,尤其是那些刚接触 Python 的人,是如何解释Python 遇到错误时显示的回溯。

在Python 3.10中,Python 的错误信息得到了极大的改进。同样,Python 3.11最受期待的功能之一也将提升您的开发者体验。装饰性注释被添加到回溯中,可以帮助您更快地解释错误消息。

要查看增强回溯的快速示例,请将以下代码添加到inverse.py的文件中:

# inverse.py

def inverse(number):
    return 1 / number

print(inverse(0))

你可以用它inverse()来计算一个数的乘法倒数。没有乘法逆元0,因此您的代码在运行时会引发错误:

$ python inverse.py
Traceback (most recent call last):
  File "/home/realpython/inverse.py", line 6, in <module>
    print(inverse(0))
          ^^^^^^^^^^
  File "/home/realpython/inverse.py", line 4, in inverse
    return 1 / number
           ~~^~~~~~~~
ZeroDivisionError: division by zero

请注意嵌入在回溯中的^和符号~,它们用于引导您注意导致错误的代码。像往常一样使用回溯,您应该从底部开始,然后逐步向上。在此示例中, aZeroDivisionError是由除法引起的1 / number。真正的罪魁祸首是inverse(0),因为0没有相反的情况。

在发现错误时获得这种额外的帮助很有用。但是,如果您的代码更复杂,带注释的回溯功能会更加强大。他们可能能够传达您以前无法从回溯中获得的信息。

要了解改进的回溯的强大功能,您将构建一个关于少数程序员的信息的小型解析器。假设您有一个名为programmers.json的文件:

[
    {"name": {"first": "Uncle Barry"}},
    {
        "name": {"first": "Ada", "last": "Lovelace"},
        "birth": {"year": 1815},
        "death": {"month": 11, "day": 27}
    },
    {
        "name": {"first": "Grace", "last": "Hopper"},
        "birth": {"year": 1906, "month": 12, "day": 9},
        "death": {"year": 1992, "month": 1, "day": 1}
    },
    {
        "name": {"first": "Ole-Johan", "last": "Dahl"},
        "birth": {"year": 1931, "month": 10, "day": 12},
        "death": {"year": 2002, "month": 6, "day": 29}
    },
    {
        "name": {"first": "Guido", "last": "Van Rossum"},
        "birth": {"year": 1956, "month": 1, "day": 31},
        "death": null
    }
]

请注意,有关程序员的信息非常不一致。虽然有关Grace Hopper和Ole-Johan Dahl的信息已完成,但您会错过Ada Lovelace 的出生日期和月份以及她的死亡年份。自然,您只有Guido van Rossum的出生信息。最重要的是,您只记录了Barry 叔叔的名字。

您将创建一个可以包装此信息的类。首先从 JSON 文件中读取信息:

# programmers.py

import json
import pathlib

programmers = json.loads(
    pathlib.Path("programmers.json").read_text(encoding="utf-8")
)

您用于pathlib读取 JSON 文件并将json信息解析为 Python 字典列表。

接下来,您将使用数据类来封装有关每个程序员的信息:

# programmers.py

from dataclasses import dataclass

# ...

@dataclass
class Person:
    name: str
    life_span: tuple[int, int]

    @classmethod
    def from_dict(cls, info):
        return cls(
            name=f"{info['name']['first']} {info['name']['last']}",
            life_span=(info["birth"]["year"], info["death"]["year"]),
        )

每个Person都有一个name和一个life_span属性。此外,您还可以添加一个方便的构造函数,该构造函数Person可以根据 JSON 文件中的信息和结构进行初始化。

您还将添加一个可以一次性初始化两个Person对象的函数:

# programmers.py

# ...

def convert_pair(first, second):
    return Person.from_dict(first), Person.from_dict(second)

该convert_pair()函数两次使用.from_dict()构造函数将一对程序员从 JSON 结构转换为Person对象。

是时候探索您的代码了,尤其是查看一些回溯。使用标志-i运行程序以打开 Python 的交互式 REPL,其中包含所有可用的变量、类和函数:

$ python -i programmers.py
>>> Person.from_dict(programmers[2])
Person(name='Grace Hopper', life_span=(1906, 1992))

Grace 的信息是完整的,因此您可以将她封装到一个Person包含有关她的全名和寿命信息的对象中。

要查看实际的新回溯,请尝试转换 Barry 叔叔:

>>> programmers[0]
{'name': {'first': 'Uncle Barry'}}

>>> Person.from_dict(programmers[0])
Traceback (most recent call last):
  File "/home/realpython/programmers.py", line 17, in from_dict
    name=f"{info['name']['first']} {info['name']['last']}",
                                    ~~~~~~~~~~~~^^^^^^^^
KeyError: 'last'

你得到一个KeyError因为last缺少。虽然您可能记得那last是name中的一个子字,但注释会立即为您指出这一点。

同样,回想一下关于 Ada 的生命周期信息是不完整的。你不能为她创建一个Person对象:

>>> programmers[1]
{
    'name': {'first': 'Ada', 'last': 'Lovelace'},
    'birth': {'year': 1815},
    'death': {'month': 11, 'day': 27}
}

>>> Person.from_dict(programmers[1])
Traceback (most recent call last):
  File "/home/realpython/programmers.py", line 18, in from_dict
    life_span=(info["birth"]["year"], info["death"]["year"]),
                                      ~~~~~~~~~~~~~^^^^^^^^
KeyError: 'year'

你得到了另一个KeyError,这次是因为year失踪了。在这种情况下,回溯比前面的例子更有用。您有两个year子字段,一个 forbirth和一个 for death。回溯注释立即显示您错过了死亡年份。

Guido怎么样了?你只有关于他出生的信息:

>>> programmers[4]
{
    'name': {'first': 'Guido', 'last': 'Van Rossum'},
    'birth': {'year': 1956, 'month': 1, 'day': 31},
    'death': None
}

>>> Person.from_dict(programmers[4])
Traceback (most recent call last):
  File "/home/realpython/programmers.py", line 18, in from_dict
    life_span=(info["birth"]["year"], info["death"]["year"]),
                                      ~~~~~~~~~~~~~^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

在这种情况下,TypeError出现了。您之前可能已经看到过这些'NoneType'类型的错误。众所周知,它们很难调试,因为不清楚哪个对象是出乎意料的None。但是,从注释中,您会看到info["death"]在此示例中是None。

在最后一个示例中,您将探索嵌套函数调用会发生什么。请记住,convert_pair()调用Person.from_dict()两次。现在,尝试将 Ada 和 Ole-Johan 配对:

>>> convert_pair(programmers[3], programmers[1])
Traceback (most recent call last):
  File "/home/realpython/programmers.py", line 24, in convert_pair
    return Person.from_dict(first), Person.from_dict(second)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/realpython/programmers.py", line 18, in from_dict
    life_span=(info["birth"]["year"], info["death"]["year"]),
                                      ~~~~~~~~~~~~~^^^^^^^^
KeyError: 'year'

尝试封装 Ada 引发与KeyError之前相同的情况。但是,请注意来自内部的回溯convert_pair()。因为该函数调用两次.from_dict(),所以通常需要一些努力才能确定在处理first或second时是否引发了错误。在最新版本的 Python 中,您会立即看到问题是由second引起的.

这些回溯使 Python 3.11 中的调试比早期版本更容易。您可以在 Python 3.11 预览教程Even Better Error Messages(https://realpython.com/python311-error-messages/)中查看更多示例、有关如何实现回溯的更多信息以及可以在调试中使用的其他工具。有关更多技术细节,请查看PEP 657(https://peps.python.org/pep-0657/)。

带注释的回溯将有助于提高 Python 开发人员的工作效率。

推荐书单

《Pandas1.x实例精解》

本书详细阐述了与Pandas相关的基本解决方案,主要包括Pandas基础,DataFrame基本操作,创建和保留DataFrame,开始数据分析,探索性数据分析,选择数据子集,过滤行,对齐索引,分组以进行聚合、过滤和转换,将数据重组为规整形式,组合Pandas对象,时间序列分析,使用Matplotlib、Pandas和Seaborn进行可视化,调试和测试等内容。此外,本书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。 本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学用书和参考手册。

链接:https://u.jd.com/UKjx4et

精彩回顾

《Pandas1.x实例精解》新书抢先看!

【第1篇】利用Pandas操作DataFrame的列与行

【第2篇】Pandas如何对DataFrame排序和统计

【第3篇】Pandas如何使用DataFrame方法链

【第4篇】Pandas如何比较缺失值以及转置方向?

【第5篇】DataFrame如何玩转多样性数据

【第6篇】如何进行探索性数据分析?

【第7篇】使用Pandas处理分类数据

【第8篇】使用Pandas处理连续数据

【第9篇】使用Pandas比较连续值和连续列

【第10篇】如何比较分类值以及使用Pandas分析库

长按关注《Python学研大本营》

长按二维码,加入Python读者群

扫码关注《Python学研大本营》,加入读者群,分享更多精彩

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/19580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT源码拾贝0-5(qimage和qpainter)

目录 0 qt源码查看方法 1. qimage.cpp中线程池使用方法 2. qpainter_p.h中SmallStack模板元结构体存放智能指针 3. qpainter.cpp的保存函数&#xff0c;状态对象赋值使用std::exchange函数 4. qpainter.cpp中获得类对象的方法 5. qpainter.cpp中QChar字节操作&…

代码随想录算法训练营三期 day 22 - 二叉树(8)

235. 二叉搜索树的最近公共祖先 原文链接&#xff1a;235. 二叉搜索树的最近公共祖先 题目链接&#xff1a;235. 二叉搜索树的最近公共祖先 在 有序树 里: 从上向下递归遍历&#xff0c;第一次遇到 curcurcur 结点的数值在 p,qp, qp,q 结点对应数值的闭区间中&#xff0c;那么…

内网渗透神器CobaltStrike之Beacon详解(三)

Beacon的种类 HTTP Beacon和HTTPS Beacon 这两个beacon的原理是通过发送http请求与受害主机通信来传达命令, 以此实现控制效果 优点是传输数据快, 缺点时隐蔽性差, 容易被防火墙或内网审计工具拦截 TCP Beacon 自CS4.0版本之后只有反向的TCP Beacon可用, 基于TCP协议的通信…

取证初级案例操作大纲

文章目录**取证初级案例操作大纲**1) 证据文件中有没有存在被删除的Doc文档&#xff1f;如果有的话&#xff0c;请导出并记录文件名及路径&#xff1a;2) 证据文件中有没有存在被删除的图片&#xff1f;如果有的话&#xff0c;请记录文件名及路径&#xff1a;3) 证据文件中哪几…

object类的一些方法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 Object类 输出对象地址 object类里的tostring方法&#xff1a; 正确输出对象里内容 判断俩个对象大小&#xff1a; object类里的equlas方法&#xff1a; 自己实现一…

SpringCloud - 微服务理论基础

文章目录1.微服务架构1.1 什么是微服务1.2 Spring Cloud 简介1.3 Spring Cloud 技术栈2.Boot 和 Cloud 版本选型3.Cloud 服务升级1.微服务架构 1.1 什么是微服务 微服务架构是一种架构模式&#xff0c;它提倡单一应用程序划分成一组小的服务&#xff0c;服务直接相互协调、相互…

Python PyInstaller 打包成 Win、Mac 应用程序(app / exe)

一、简介 python 提供了几个用来打包的模块&#xff0c;主要有 py2app、py2exe、pyinstaller。附&#xff1a;pyinstaller、py2app、py2exe、fbs 对比与爬坑。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-whT6cPog-1668880648443)(https://p1-jue…

(续)SSM整合之springmvc笔记(RESTful之HiddenHttpMethodFilter源码解析)(P147)了解

RESTful之HiddenHttpMethodFilter源码解析 由于浏览器只支持发送get和post方式的请求&#xff0c;那么该如何发送put和delete请求呢&#xff1f; SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们将POST 请求转换为DELETE 或PUT 请求 HiddenHttpMethodFilter 处理put和delete…

java计算机毕业设计ssm陕理工图书馆管理系统

项目介绍 随着互联网技术的发发展,计算机技术广泛应用在人们的生活中,逐渐成为日常工作、生活不可或缺的工具,高校各种管理系统层出不穷。高校作为学习知识和技术的高等学府,信息技术更加的成熟,为高校图书馆借阅开发必要的系统,能够有效的提升管理效率。一直以来,高校图书馆一…

Docker搭建Redis集群

Docker搭建Redis集群 注意&#xff1a;Redis搭建集群最少需要6个Redis节点&#xff0c;其中3个作为主节点&#xff0c;3个作为从节点&#xff1b; 为了方便&#xff0c;这里用Docker在一台机器上启动6个容器来作为集群&#xff0c;生产上建议用多台服务器搭建&#xff1b; 创建…

4.1.3 名称的特殊处理

名称的特殊处理 类成员变量的名称处理&#xff1a; 对于类的数据成员&#xff0c;其的名称经过编译器的处理会在程序员定义名称的后面再加上class的名称&#xff0c;进而形成独一无二的命名&#xff0c;例如下面的的成员变量x再经过类处理后有可能为x_7Point3d。 class Point…

Linux之手把手教你捋清楚make和makefile

文章目录背景简单介绍make和makefile依赖关系和依赖方法项目清理以及伪目标背景 以往的C语言编程&#xff0c;我们一般都在一些像VS2019这样的集成开发环境(IDE)下编写&#xff0c;一个工程中的源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0…

Spring框架的概述及基本应用

Spring的基本应用 文章目录Spring的基本应用1. Spring 概述1.1 什么是Spring1.2 Spring 框架的优点1.3 Spring的体系结构2. Spring的核心容器2.1 BeanFactory2.2 ApplicationContext3. Spring的入门程序3.1 在pom下利用maven导入Spring所需要的jar包3.2 简单搭建起demo结构3.3 …

Java中数组的定义与使用(Java系列3)

目录 前言&#xff1a; 1.什么是数组 2.数组的创建 3.数组的初始化 4.数组的使用 5.数组是引用类型 6.基本类型变量与引用类型变量的区别 7.数组的应用 8.二维数组 结束语&#xff1a; 前言&#xff1a; 前面小编与大家分享了C语言与Java中的区别&#xff0c;还有一…

leaflet教程041: Point 和 LatLng 坐标互相转换

第041个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中使用Point和LatLng,这里做了两者之间的转换。 注意 两者转换后的值,返回相对于原点像素的相应像素坐标或经纬度坐标。zoom改变,原点(地图图层左上角的投影像素坐标)的值会改变,所以获得的值也会变化。…

51单片机学习笔记1 简介及开发环境

51单片机学习笔记1 简介及开发环境一、51单片机1. STC89C52单片机简介2. 命名规则3. 封装&#xff08;1&#xff09;PDIP&#xff08;2&#xff09;LQFP&#xff08;3&#xff09;PLCC&#xff08;4&#xff09;PQFP二、STC8051结构1. STC 8051 内部结构图2. 内部结构框图3. 单…

Android设置TabLayout熟悉及下划线宽度

Tablayout的使用 属性 app&#xff1a;tabMod 设置Tab模式 app&#xff1a;tabTextColor 设置文本颜色 app&#xff1a;tabSelectedTextColor 设置选中文本颜色 app:tabIndicatorColor 设置下滑条颜色 app:tabMaxWidth“xxdp” 设置最大的tab宽度 app:tabMinWidth“xxdp” 设置…

牛客网之SQL100题(7)-字符串截取、切割、删除、替换

知识点&#xff1a; &#xff08;1&#xff09;substring_indexsubstring_index(str,delim,count) str:要处理的字符串 delim:分隔符 count:计数 &#xff08;2&#xff09;切割、截取、删除、替换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 select -- 替换法 replace(string, 被…

类型转换C11

类型转换 C类型转换分为显式类型转换和隐式类型转换 &#xff0c;隐式类型转换由编译器自动完成&#xff0c;这里只讨论显式类型转换。 旧式风格的类型转换 type(expr); // 函数形式的强制类型转换 (type)expr; // C语言风格的强制类型转换现代C风格的类型转换 cast-name&l…

1-2 VMware安装Rocky9.0和Ubuntu22.04系统

文章目录前言下载链接VMware使用安装Rocky9.0系统Rocky初始化安装Ubuntu22.04系统Ubuntu初始化VMware快照前言 VMware虚拟机软件是一个“虚拟PC”软件&#xff0c;它使你可以在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。 Rocky Linux 9.0 操作系统与2022年7月14…