我的编程空间,编程开发者的网络收藏夹
学习永远不晚

13 个 python3 才能用的特性

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

13 个 python3 才能用的特性

分享来源13 个 python3 才能用的特性

python3 于 2008 年发布,从最初的大割裂到现在,绝大多数的开源库已经使用 python3 来编写,并且已经迭代了五个大版本,最新的 python3.7 计划于 2018 年 6 月 15 发布正式版。而 python2.7 作为 python2 的最后一个版本,将于 2020 年 1 月停止维护。

更多Python视频、源码、资料加群683380553免费获取

python3 的使用率在很久的一段时间里增长非常缓慢,是的,大多数人只觉得 python3 只是改了输出语句 print(),而并没有意识到实际上 python3 所具有的大量新特性。虽然说可以用 import __future__ 来在 python2 使用部分特性,但是以下 13 点非常好用的特性是你在 python2 中完全无法体验到的。

 

我们从 https://www.asmeurer.com/python3-presentation/slides.html 中整理并翻译了 python3 的特性,剔除了部分老旧的代码,整理了相关例子,并提供了 jupyter notebook 版本以及 html 版,获取方法在本文末。

 

特性 1: 高级解包

交换两个变量的值在 python 中非常简单,你也许已经在 python2 中大量使用以下方法:


a, b = 1, 2
a, b = b, a
print(a, b)
##> 2, 1

 

使用解包交换变量非常方便,在 python3 中,这个特性得到了加强,现在你可以这样做:


a, b, *rest = range(10)
print('a:', a)
print('b:', b)
print('rest:', rest)
##> a: 0
##> b: 1
##> rest: [2, 3, 4, 5, 6, 7, 8, 9]

 

rest 可以在任何位置,比如这样:


a, *rest, b = range(10)
print('rest', rest)
##> rest [1, 2, 3, 4, 5, 6, 7, 8]

*rest, b = range(10)
print('rest', rest)
##> rest [0, 1, 2, 3, 4, 5, 6, 7, 8]

 

使用 python 获得文件的第一行和最后一行内容。


with open('use_python_to_profit.txt') as f:
    first, *_, last = f.readlines() # 注意,这会读取所有内容到内存中

print('first:', first)
print('last:', last)
##> first: step 1: use python
##> last: step 10: profit

 

特性 2: 强制关键词参数


def f(a, b, *args, option=True):
    pass

 

如果你用以上写法来写一个函数,那么你限定了调用参数时,必须要这样写 f(a, b, option=True)

如果你不想收集其他参数,你可以用 * 代替 *args,比如这样:


def f(a, b, *, option=True):
    pass

 

当你碰上这种事情:哎呀,我不小心传递太多参数给函数,其中之一会被关键字参数接收,然后程序原地爆炸了。


def sum(a, b, biteme=False):
    if biteme:
        print('一键删库')
    else:
        return a + b

sum(1, 2)
##> 3
sum(1, 2, 3)
##> 一键删库.

.. .所以,以后千万别这样写,为了你的下半生能够过上平静的日子,你应该这样:


def sum(a, b, *, biteme=False):
    if biteme:
        print('一键删库')
    else:
        return a + b

 

试一下不合法的调用:


sum(1, 2, 3)
##> TypeError: sum() takes 2 positional arguments but 3 were given

 

有时你会想写这样一个方法


def maxall(iterable, key=None):
    """
    返回一个列表中的最大值
    """
    key = key or (lambda x: x)
    m = max(iterable, key=key)
    return [i for i in iterable if key(i) == key(m)]

maxall(['a', 'ab', 'bc'], len)
##> ['ab', 'bc']

 

但是你又想像内置的max()函数那样允许 max(a, b, c) 的写法,但是这两种传参方法似乎不能和平相处:


def maxall(*args, key=None):
   """
   A list of all max items from the iterable
   """
   if len(args) == 1:
       iterable = args[0]
   else:
       iterable = args
   key = key or (lambda x: x)
   m = max(iterable, key=key)
   return [i for i in iterable if key(i) == key(m)]

maxall(['a', 'bc', 'cd'], len)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-e8f4c154d310> in <module>()
     11     return [i for i in iterable if key(i) == key(m)]
     12 
---> 13 maxall(['a', 'bc', 'cd'], len)

<ipython-input-22-e8f4c154d310> in maxall(key, *args)
      8         iterable = args
      9     key = key or (lambda x: x)
---> 10     m = max(iterable, key=key)
     11     return [i for i in iterable if key(i) == key(m)]
     12 

TypeError: unorderable types: builtin_function_or_method() > list()

 

显然,我们应该用max(iterable, *, key=None)来写这个函数。你在写代码时,也可以用关键词参数使你的 api 具有更好的扩展性。


# 蠢蠢的写法
def extendto(value, shorter, longer):
    """
    使短的 list 填充到和长的 list 一样长,填充为 value
    """
    if len(shorter) > len(longer):
        raise ValueError('The `shorter` list is longer than the `longer` list')
    shorter.extend([value]*(len(longer) - len(shorter)))

a = [1, 2]
b = [1, 2, 3, 4, 5]

extendto(10, a, b)

print('a', a)
##> a [1, 2, 10, 10, 10]

 

当你碰上这种事情:哎呀,我不小心传递太多参数给函数,其中之一会被关键字参数接收,然后程序原地爆炸了。


# 更好的写法
def extendto(value, *, shorter=None, longer=None):
    """
    Extend list `shorter` to the length of list `longer` with `value`
    """
    if shorter is None or longer is None:
        raise TypeError('`shorter` and `longer` must be specified')
    if len(shorter) > len(longer):
        raise ValueError('The `shorter` list is longer than the `longer` list')
    shorter.extend([value]*(len(longer) - len(shorter)))

 

我们可以用 extendto(10, shorter=a, longer=b) 的方式调用这个方法,以后我们要修改这个接口的传参方式时,也不用修改已有代码啦。

 

特性 3:链式异常

现在你在写一个函数,由于可能会出现错误,你打算 catch 可能出现的异常,做一些额外的工作,然后再抛出另一种异常。


import shutil

def mycopy(source, dest):
    try:
        shutil.copy2(source, dest)
    except OSError: # We don't have permissions. More on this later
        raise NotImplementedError("automatic sudo injection")

 

如果你用 python2 的话得到的是,你把第一个异常信息丢了,只能一脸懵逼。


>>> mycopy(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in mycopy
NotImplementedError: automatic sudo injection

 

python3 中会依次把异常记录下来


mycopy(1, 2)

---------------------------------------------------------------------------
SameFileError                             Traceback (most recent call last)
<ipython-input-26-7970d14296a0> in mycopy(source, dest)
      4     try:
----> 5         shutil.copy2(source, dest)
      6     except OSError: # We don't have permissions. More on this later

/usr/lib/python3.5/shutil.py in copy2(class="lazy" data-src, dst, follow_symlinks)
    250         dst = os.path.join(dst, os.path.basename(class="lazy" data-src))
--> 251     copyfile(class="lazy" data-src, dst, follow_symlinks=follow_symlinks)
    252     copystat(class="lazy" data-src, dst, follow_symlinks=follow_symlinks)

/usr/lib/python3.5/shutil.py in copyfile(class="lazy" data-src, dst, follow_symlinks)
     97     if _samefile(class="lazy" data-src, dst):
---> 98         raise SameFileError("{!r} and {!r} are the same file".format(class="lazy" data-src, dst))
     99 

SameFileError: 1 and 2 are the same file

During handling of the above exception, another exception occurred:

NotImplementedError                       Traceback (most recent call last)
<ipython-input-27-ddb6bcd98254> in <module>()
      1 # python3 中会依次把异常记录下来
----> 2 mycopy(1, 2)

<ipython-input-26-7970d14296a0> in mycopy(source, dest)
      5         shutil.copy2(source, dest)
      6     except OSError: # We don't have permissions. More on this later
----> 7         raise NotImplementedError("automatic sudo injection")

NotImplementedError: automatic sudo injection

 

特性 4: 更好用的 OSError 子类

刚刚给你的代码其实不正确,OSError 实际上包含了很多类异常,比如权限不够,文件没找到,不是一个目录等,而我们默认是权限不够。你在 python2 中可能是这样来区分 OSError 的:


import errno
def mycopy(source, dest):
    try:
        shutil.copy2(source, dest)
    except OSError as e:
        if e.errno in [errno.EPERM, errno.EACCES]:
            raise NotImplementedError("automatic sudo injection")
        else:
            raise

 

python3 添加了大量的新 Exception 类型 https://docs.python.org/3.4/library/exceptions.html#os-exceptions ,所以现在你可以这样做:


def mycopy(source, dest):
    try:
        shutil.copy2(source, dest)
    except PermissionError:
        raise NotImplementedError("automatic sudo injection")

 

特性 5: 一切皆迭代器

python2 中已经有迭代器了,然而 emmmm


def naivesum(N):
    A = 0
    for i in range(N + 1):
        A += i
    return A

naivesum(100000000) # 内存爆炸

当然,python2 中可以用 xrange 来解决这个问题,你还可以使用 itertools.izip, dict.itervalues 替代 zip 和 dict.values…… 在 python3 中,range,zip,dict.values 以及其它,都是返回迭代器,所以这对内存很友好。

如果你希望得到一个列表,要做的仅仅是在外层加一个 list,显示的声明永远比隐式地更好,你很难再写出一个吃内存的代码了。

 

特性 6: 不是一切都能比较

在 python2 中,你可以这么写


>>> max(['one', 2])
'one'

>>> "abc" > 123
True

>>> None > all
False

在 python3 中,这个非常 buggy 的特性被取消啦:


'one' > 2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-33-55b5025c2335> in <module>()
----> 1 'one' > 2

TypeError: unorderable types: str() > int()

 

特性 7: yield from

如果你用 generator 的话,这个是一个非常好的特性。在以前,你是这么写代码的:


for i in gen():
    yield i

现在是这样


yield from gen()

 

没有看懂?来一个例子,比如这样,我们希望得到 [0, 0, 1, 1, 2, 2, ...] 的列表用于迭代,我们有以下写法:

 


# 蠢蠢的方法,直接生成对应的列表
def dup(n):
    A = []
    for i in range(n):
        A.extend([i, i])
    return A

# 不错的方法,使用 yield
def dup(n):
    for i in range(n):
        yield i
        yield i

# 更好的方法,使用 yield from
def dup(n):
    for i in range(n):
        yield from [i, i]

 

我们知道,迭代器的方式非常好,首先在内存上它很有优势,并且可以按需计算,每次只计算要用的值。如果你需要一个列表的时候,只需要在外层加一个 list,如果你需要切片 slicing,可以用 itertools.islice()

 

特性 8: asyncio

现在你可以用更方便的协程调用了


async def fetch(host, port):
    r, w = await open_connection(host, port)
    w,write(b'GET /HTTP/1.0\r\n\r\n')
    while (await r.readline()).decode('latin-1').strip():
        pass
    body = await r.read()
    return body

async def start():
    data = await fetch('Welcome to Python.org', 80)
    print(data.deode('utf-8'))

 

特性 9: 新的标准库

ipaddress 库


import ipaddress

print(ipaddress.ip_address('192.168.0.1'))
print(ipaddress.ip_address('2001:db8::'))
##> 192.168.0.1
##> 2001:db8::

 

functools.lrc_cache 装饰器


from functools import lru_cache
from urllib.error import HTTPError
import urllib.request

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'http://www.python.org/dev/peps/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except HTTPError:
        return 'Not Found'

for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
    pep = get_pep(n)
    print(n, len(pep))

get_pep.cache_info()
##> CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

 

enum 类


from enum import Enum

class Color(Enum):
    red = 1
    green = 2
    blue = 3

 

特性 10: Fun

听说你会中文编程?


简历 = "knows python"
π = 2.1415936

 

类型标注


def f(a: int, b: int = 2) -> int:
    return 10

print(f.__annotations__)
##> {'return': <class 'int'>, 'a': <class 'int'>, 'b': <class 'int'>}

 

特性 11: Unicode 编码

这是新手遇到的最多的问题,为什么我的命令行输出是乱码?

python2 中的 str 是字节数组

python3 中的 str 是 unicode 字符串,只有 unicode 才能表示中文。

 

特性 12: 矩阵相乘

python3 中 @ 可以被重载了,所以用 numpy 中的矩阵乘法时可以这么来(我在 tensorflow 中也经常这样写)


import numpy as np

a = np.array([[1, 0], [0, 1]])
b = np.array([[4, 1], [2, 2]])

# 旧写法
print(np.dot(a, b))
# 新写法
print(a @ b)

 

特性 13: pathlib

这是一个特别好用的面向对象路径处理库,以下是旧写法


import os

directory = "/etc"
filepath = os.path.join(directory, "hosts")

if os.path.exists(filepath):
    print('hosts exist')

 

更好的写法


from pathlib import Path

directory = Path("/etc")
filepath = directory / "hosts"

if filepath.exists():
    print('hosts exist')

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

13 个 python3 才能用的特性

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

13 个 python3 才能用的特性

分享来源13 个 python3 才能用的特性python3 于 2008 年发布,从最初的大割裂到现在,绝大多数的开源库已经使用 python3 来编写,并且已经迭代了五个大版本,最新的 python3.7 计划于 2018 年 6 月
2023-01-31

惊艳!Python3 的这几个特性

距离官方放弃Python2的时间越来越近,很多项目也逐渐的开始放弃对Python2的支持,比如Django,IPython这些框架就走在了最前列,Python2完成了它的使命,在人工智能的新时代,Python2带来的问题不断地困扰开发者,比
2023-01-31

python的13个特性分别是什么

python的13个特性分别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。如果你是一个正在学习python的c、c++或者java程序员,或者你是刚开始学python
2023-06-02

你应该使用Python3里的这些新特性

概述由于Python2的官方维护期即将结束,越来越多的Python项目从Python2切换到了Python3。可是,在实际的工作中,我发现好多人都是在用Python2的思维去写Python3的代码,Python3给我们提供了很多新的、很方便
2023-01-31

PHP 函数新特性如何促进 web 应用的性能?

通过利用 php 函数新特性,如 filter_var()、array_chunk() 和 in_array(),可以显著提升 web 应用程序性能:filter_var() 过滤输入,提高数据安全性。array_chunk() 划分大数组
PHP 函数新特性如何促进 web 应用的性能?
2024-05-01

Redis 的基本特性和 5 个常用数据结构

[TOC]1. 基本特性速度快基于 C 语言开发,源码短小精悍数据存在内存中单线程(高性能)支持数据持久化,异步保存到磁盘丰富的数据结构(key-value):string、list、hash、set、zset多语言客户端功能丰富:发布订阅;Lua 脚本;等简
Redis 的基本特性和 5 个常用数据结构
2019-02-26

监控 MongoDB 性能的 5 个有用工具

随着越来越多的企业转向 MongoDB 进行数据库管理,密切关注其性能非常重要。监控 MongoDB 性能可以帮助您识别任何潜在问题、防止停机并提高数据库的整体效率。这里有 5 个监控 MongoDB 性能的有用工具 -MongoDB
2023-10-22

几个常用的linux性能监控命令

1. sar 每两秒刷新一次, 总共5次 [root@dbhost01 ~]# sar 2 5Linux 2.6.32-504.el6.x86_64 (dbhost01) 03/30/2018 _x86_64_(4 CPU)02:53:1
2023-06-06

18个常用的网站性能测试工具

以下是18个常用的网站性能测试工具:1. Google PageSpeed Insights2. GTmetrix3. Pingdom Tools4. WebPageTest5. YSlow6. Load Impact7. Apache J
2023-09-16

18个常用的网站性能测试工具

18个常用的网站性能测试工具WebPageTest:提供免费且详细的性能分析,支持各种测试选项。GTmetrix:进行广泛的性能分析,生成GooglePageSpeedInsights和YSlow报告。Pingdom:付费服务,提供正常运行时间监控和高级报告。LoadImpact:模拟高并发量,识别性能瓶颈。WebLOAD:企业级负载测试,支持移动和API测试。JMeter:开源且高度可配置的负载测试工具。Gatling:高性能和可扩展的开源负载测试工具。ApacheJMeter:流行的开源负载测试工具,
18个常用的网站性能测试工具
2024-04-10

C++ 内存管理如何优化特定应用程序的性能?

c++++ 内存管理优化可提升应用程序性能,涉及以下优化策略:减少分配和释放,使用缓存和智能指针;选择合适分配器,例如 std::malloc 或自定义分配器;优化布局,使用 alignas 关键字;实战案例:图像处理应用程序可使用 std
C++ 内存管理如何优化特定应用程序的性能?
2024-05-24

如何使用python搭建一个高性能的网站

作为一名程序员,还是必须要会开发网站的,不然别人都会怀疑你是不是程序员了。今天,主要介绍一下如何使用python来搭建一个网站。可能有人会觉得搭建网站不都应该用java么?python的性能那么低。的确,使用java来开发网站的确要比pyt
2023-01-31

云服务器的主要性能参数有哪些特点和作用

云服务器是一种虚拟服务器软件,通常被用于云计算平台,提供高性能、可靠性和安全性方面的服务。下面是云服务器的主要性能参数和作用:处理速度:云服务器可以处理数百个并发请求或数万个请求,因此它们比传统的独立服务器要快得多。弹性伸缩性:云服务器可以在不降低处理速度的前提下按需增加或减少容量,从而实现更好的弹性伸缩性。负载均衡功能:云服务器可以将不同的计算资源分隔成多个独立的虚拟机,以确保每个计算
2023-10-26

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录