返回顶部
首页 > 资讯 > 后端开发 > Python >Python 3.7 新特性概览(附实例
  • 476
分享到

Python 3.7 新特性概览(附实例

新特性实例Python 2023-01-31 07:01:07 476人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

译自:https://hackaday.com/2018/07/23/hands-on-with-python-3-7-whats-new-in-the-latest-release/?utm_source=mybridge&ut

译自:https://hackaday.com/2018/07/23/hands-on-with-python-3-7-whats-new-in-the-latest-release/?utm_source=mybridge&utm_medium=blog&utm_campaign=read_more

目录

内置 breakpoint()

注解和类型

计时

Dataclass

其他

结论


许多人使用的第一种、被称为世界上增长最快的编程语言当然是 Python,可用于通用编程、数据科学、网站后端、GUI 以及几乎所有其他功能。最新的 3.7.0 版本 刚发布不久。

任何版本 Python 的发行,无论变化多小,在任何开发开始之前都要经过细致的规划和设计。实际上,你可以阅读 Python 3.7 的PEP (Python Enhancement Proposal,Python 增强提议),该提议是在2016年创建的。

3.7 中有什么新功能?你为什么要升级?有什么新的有用的东西吗?我将通过介绍一些新特性的例子来回答这些问题。虽然这个版本对 Python 初学者来说没有什么不同,但是对于经验丰富的程序员来说有很多小的变化,还有一些你想要了解的主要特性。


任何使用过 pdb (Python debugger) 的人都知道它有多么强大。它能暂停脚本的执行,允许你在程序的内部手动浏览,并且单步执行语句。

但是,到目前为止,在编写程序时需要进行一些设置。当然,导入 pdb 和 set_trace() 几乎不需要花费任何时间,但这不如插入快速调试 print() 或 log 方便。在 Python 3.7 中,breakpoint() 是内置函数,可以非常容易地在任何时候插入调试器。同样值得注意的是,pdb 只是众多可用调试器之一,你可以通过设置新的 PYTHONBREAKPOINT 环境变量来配置想要使用的调试器。

这里有一个简单例子。用户需要输入一个字符串,判断它是否匹配一个值。


"""Test user's favourite Integrated Circuit."""
 
def test_ic(favourite_ic):
    user_guess = input("Try to guess our favourite IC >>> ")
 
    if user_guess == favourite_ic:
        return "Yup, that's our favourite!"
    else:
        return "Sorry, that's not our favourite IC"
 
 
if __name__ == '__main__':
    favourite_ic = 555
    print(test_ic(favourite_ic))

不幸的是,无论输入什么,我们都无法匹配字符串。


$ python breakpoint_test.py
Try to guess our favourite IC >>> 555
Sorry, that's not our favourite IC

为了弄清楚发生了什么,让我们插入一个断点 —— 只需要调用 breakpoint()


"""Test user's favourite Integrated Circuit."""
 
def test_ic(favourite_ic):
    user_guess = input("Try to guess our favourite IC >>> ")
    breakpoint()
 
    if user_guess == favourite_ic:
        return "Yup, that's our favourite!"
    else:
        return "Sorry, that's not our favourite IC"
 
 
if __name__ == '__main__':
    favourite_ic = 555
    print(test_ic(favourite_ic))

在 pdb 提示符下,我们将调用 locals() 来调出当前的本地作用域。pdb 有大量有用的命令,但是你也可以在其中运行正常的Python 语句。


$ python breakpoint_test.py
Try to guess our favourite IC >>> 555
> /home/ben/Hackaday/python37/breakpoint_test.py(8)test_ic()
-> if user_guess == favourite_ic:
(Pdb) locals()
{'favourite_ic': 555, 'user_guess': '555'}
(Pdb)

啊哈!看起来 favourite_ic 是一个整数,而 user_guess 是一个字符串。因为在 Python 中,将字符串与 int 进行比较是完全可行的,所以没有抛出异常(但是比较没有达到我们想要的效果)。favourite_ic 应该声明为字符串,这可以说是 Python 的动态类型的危险之一 —— 在运行时之前无法捕捉到这个错误。当然,除非你使用类型注解……


从 Python 3.5 开始,类型注解就越来越受欢迎。对于那些不熟悉类型提示的人来说,这是一种完全可选的注释代码的方式,以指定变量的类型。

类型提示(Type hints)只是 annotations 的一个应用。注解是什么?它们是关联元数据与变量的语法支持,可以是任意表达式,在运行时被 Python 计算但被忽略。注解可以是任何有效的 Python 表达式。这里有一个带注解的函数的例子,但这个例子中使用了一些无用的信息。


# Without annotation
def foo(bar, baz):
# Annotated
def foo(bar: 'Describe the bar', baz: print('random')) -> 'return thingy':

这一切都很酷,但有点无意义,除非以标准方式使用注解。在 Python 3.5 (PEP 484)中,使用注解进行编程的语法变得标准化,此后,Python 社区广泛使用了类型提示。它们纯粹是一种开发工具,可以使用 PyCharm 等 IDE 或 Mypy 等第三方工具进行检查。

如果我们的字符串比较程序是用类型注解编写的,它应该是这样的:


"""Test user's favourite Integrated Circuit."""
 
def test_ic(favourite_ic: str) -> str:
    user_guess: str = input("Try to guess our favourite IC >>> ")
    breakpoint()
 
    if user_guess == favourite_ic:
        return "Yup, that's our favourite!"
    else:
        return "Sorry, that's not our favourite IC"
 
 
if __name__ == '__main__':
    favourite_ic: int = 555
    print(test_ic(favourite_ic))

你可以看到 PyCharm 提醒了我这个错误,它可以防止我在运行时才注意到它。

这就是注解和类型提示的基础。Python 3.7 中有什么变化?正如官方的 Python 文档所指出的,当人们开始使用注解作为类型提示时,出现了两个主要问题:启动性能和前向引用。

  • 不出意外的是,在定义时计算大量任意表达式相当影响启动性能,而且 typing 模块非常慢
  • 你不能用尚未声明的类型来注解

这种缺乏前向引用的做法似乎是合理的,但在实践中却变得相当麻烦。


class User:
    def __init__(self, name: str, prev_user: User) -> None:
        pass

这种做法将失败,因为 User 还没有被声明,因此 prev_user 不能定义为 User 类型。

为了解决这两个问题,注解的评估被推迟。

要实现上述行为,必须导入 __future__,因为在保持与以前版本兼容的情况下无法进行此更改。


from __future__ import annotations
 
class User: 
    def __init__(self, name: str, prev_user: User) -> None:
        pass

typing 模块如此缓慢的部分原因是,最初的设计目标是在不修改核心 CPython 解释器的情况下实现 typing 模块。既然类型提示变得越来越流行,这一限制已经被移除,这意味着现在有了对 typing 的核心支持,使得支持多种优化


time 模块在定时上加入了一些新功能:现有的定时器功能达到了纳秒级,这意味着如果需要的话,可以有更高的精度。一些基准测试表明,time.time() 的分辨率是 time.time_ns() 的三倍以上。

说到时间,Python 本身在 3.7 中获得了一个小的速度提升。这是底层的内容,所以我们现在不深入讨论,这里有完整的优化列表。你只需要知道,在 linux 上的启动时间比之前要快 10%,在 MacOS 上快 30%,大量的方法调用要快 20%。


我敢打赌,如果你曾经编写过面向对象的 Python,你就会创建一个类,最终看起来像这样:


class User:
 
    def __init__(self, name: str, age: int, favourite_ic: str) -> None:
        self.name = name
        self.age = age
        self.favourite_ic = favourite_ic
 
    def is_adult(self) -> bool:
        """Return True if user is an adult, else False."""
        return self.age >= 18
 
 
if __name__ == '__main__':
    john = User('John', 29, '555')
    print(john)
    # prints "<__main__.User object at 0x0076E610>"

当类被初始化时,__init__ 会接收到大量不同的参数。这些属性直接设置为类实例的属性,供以后使用。在编写这类类时,这是一种非常常见的模式 —— 但这是Python,如果可以避免单调乏味,那么它就可以。

在 3.7 中,我们有 dataclass,这将使这类类更容易声明,也更可读。

只需用 @dataclass 装饰类,self 的赋值就会自动处理。变量的声明如下所示,类型注解是强制性的(如果你想灵活的话,你仍然可以使用 Any 类型)。


from dataclasses import dataclass
 
@dataclass
class User:
    name: str
    age: int
    favourite_ic: str
 
    def is_adult(self) -> bool:
        """Return True if user is an adult, else False."""
        return self.age >= 18
 
if __name__ == '__main__': 
    john = User('John', 29, '555') 
    print(john) 
    # prints "User(name='John', age=29, favourite_ic='555')"

这使得类不仅容易设置,而且当我们创建一个实例并打印出来时,它还生成了一个优美的字符串。在与其他类实例进行比较时,它也会有适当的行为。这是因为,除了自动生成 __init__ 方法外,还生成了其他特殊方法,如 __repr____eq____hash__ 等。当定义这样的类时,大大减少了所需的开销。

Dataclass 使用字段 (field) 来完成它们的工作,手动构造一个 field() 函数能够访问其他选项,从而更改默认值。例如,这里将 field 中的 default_factory 设置为一个 lambda 函数,该函数提示用户输入其名称。


from dataclasses import dataclass, field
 
class User:
    name: str = field(default_factory=lambda: input("enter name"))

(我们不建议直接将 input 输入到属性中,这只是一个字段功能的演示。)


在这个版本中还有许多其他的变化;我们将在这里列出一些最重要的:

  • 字典现在保持插入顺序。这在 3.6 中是非正式的,但现在是官方语言规范。在大多数情况下,普通的 dict 应该能够替换 collections.OrderedDict
  • 加入法文、日文和韩文文档翻译
  • 对模块属性访问的控制现在更容易了,因为 __getattr__ 现在可以在模块层次进行定义。这使得定制导入行为和实现特性,例如弃用警告,变得更加容易。
  • CPython 的一种新的开发模式
  • .pyc 文件具有确定性,支持可重复构建 —— 也就是说,总是为相同的输入文件生成相同的 byte-for-byte 输出。

有一些非常简洁的语法快捷方式和性能改进,但这可能不足以鼓励每个人进行升级。总的来说,Python 3.7 实现了一些特性,这些特性将真正减少混乱的代码解决方案,并生成更干净的代码。我们当然期待使用它,也等不及 3.8 的到来!

--结束END--

本文标题: Python 3.7 新特性概览(附实例

本文链接: https://lsjlt.com/news/190726.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python 3.7 新特性概览(附实例
    译自:https://hackaday.com/2018/07/23/hands-on-with-python-3-7-whats-new-in-the-latest-release/utm_source=mybridge&utm...
    99+
    2023-01-31
    新特性 实例 Python
  • MySQL 8.0新特性概览
    1.事务性数据字典,完全脱离了MyISAM存储引擎 真正将数据字典放到了InnoDB中的一些表中,从此不再需要FRM、TRG、PAR文件啦!Information Schema现在以数据字典表的一个视图出现...
    99+
    2024-04-02
  • Win10 10074最新预览版用户界面新特性概览
    伴随着微软 Build 2015 开发者大会,Windows 10 insider Preview Build 10074 不期而至,新的版本在用户界面上改动很大,请跟随笔者共同体验。 1、开始菜单...
    99+
    2023-06-14
    Win10 10074 用户界面 预览 概览 特性
  • Python 3.9.0新特性实例分析
    这篇文章主要介绍“Python 3.9.0新特性实例分析”,在日常操作中,相信很多人在Python 3.9.0新特性实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python 3.9.0新特性实例分析...
    99+
    2023-06-27
  • JDK8新特性实例分析
    这篇“JDK8新特性实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JDK8新特性实...
    99+
    2024-04-02
  • Java8新特性StreamAPI实例详解
    目录Stream结果收集结果收集到集合中结果收集到数组中对流中的数据做聚合计算对流中数据做分组操作对流中的数据做分区操作对流中的数据做拼接并行的Stream流串行的Stream流并行...
    99+
    2022-11-13
    Java8新特性 StreamAPI Java8 StreamAPI
  • Java新特性使用实例分析
    这篇文章主要介绍“Java新特性使用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java新特性使用实例分析”文章能帮助大家解决问题。枚举:尽管在 JDK 5 中增加了枚举类型,但是 Cla...
    99+
    2023-06-27
  • JDK19新特性使用实例详解
    目录前提新特性列表新特性使用详解Record模式Linux/RISC-V移植外部函数和内存API虚拟线程向量APIswitch匹配模式结构化并发前提 JDK19于2022-09-20...
    99+
    2024-04-02
  • Java8新特性之Collectors.joining()实例详解
    目录方法定义无参方法单个参数多个参数如果流中的数据是字符串如果流中的数据是对象总结方法定义 Java 8 流 ( stream ) 收集器 ( Collectors ) 中的&nbs...
    99+
    2023-01-12
    java8新特性collectors.joining() java8 collectors.joining()
  • 【恩墨学院】经典文档:Oracle Database 12.2新特性概览解读下载
    【恩墨学院】经典文档:Oracle Database 12.2新特性概览解读下载 关于In-Memory选件,12.2 的重要增强是在 ADG 实现 In-Memory 缓存,并且可以和主库以...
    99+
    2024-04-02
  • Java 17新特性讲解与代码实例
    Java 17是Java SE 17的开源参考实现,于2021年9月14日正式发布,是Java 11以来的又一个长期支持(LTS)版本。Java 17中有一些新的特性和改进,本文将对它们进行简要的介绍和示例。 密封类 密封类和接口限制了哪些...
    99+
    2023-09-07
    java 开发语言 java17
  • Go1.18新特性之泛型实例代码分析
    本篇内容主要讲解“Go1.18新特性之泛型实例代码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go1.18新特性之泛型实例代码分析”吧!1. 一切从函数的形参和实参说起假设我们有个计算两数...
    99+
    2023-07-05
  • PHP 函数新特性在实际应用中的优势示例有哪些?
    php 新特性在实际应用中提供了显著优势:箭头函数:简化匿名函数语法,提高可读性。匹配表达式:提供更简洁的模式匹配,提升代码可读性。解构赋值:轻松提取数据结构的一部分,简化数据处理。nu...
    99+
    2024-05-04
    php 函数新特性 代码可读性
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作