Python2即将淘汰,分享python3 才能用的特性(13个)

特性 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(iterable, *, key=None)来写这个函数。你在写代码时,也可以用关键词参数使你的 api 具有更好的扩展性。

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")

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(src, dst, follow_symlinks)
    250         dst = os.path.join(dst, os.path.basename(src))
--> 251     copyfile(src, dst, follow_symlinks=follow_symlinks)
    252     copystat(src, dst, follow_symlinks=follow_symlinks)

/usr/lib/python3.5/shutil.py in copyfile(src, dst, follow_symlinks)
     97     if _samefile(src, dst):
---> 98         raise SameFileError("{!r} and {!r} are the same file".format(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 实际上包含了很多类异常,比如权限不够,文件没找到,不是一个目录等,而我们默认是权限不够。

python3 添加了大量的新 Exception 类型,所以你可以这样做:

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

特性 5: 一切皆迭代器

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

naivesum(100000000) # 内存爆炸

在 python3 中,range,zip,dict.values 以及其它,都是返回迭代器,所以这对内存很友好。

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

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

在 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, ...] 的列表用于迭代,我们有以下写法:

# 不错的方法,使用 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"
π = 3.1415926

类型标注

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

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

from pathlib import Path

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

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

原文地址:https://www.cnblogs.com/rrh4869/p/11175390.html

时间: 2024-08-30 18:26:07

Python2即将淘汰,分享python3 才能用的特性(13个)的相关文章

使用python3自带工具2to3.py 转换 python2.x 代码 到python3

几乎所有的Python 2程序都需要一些修改才能正常地运行在Python 3的环境下.为了简化这个转换过程,Python 3自带了一个叫做2to3的实用脚本(Utility Script),这个脚本会将你的Python 2程序源文件作为输入,然后自动将其转换到Python 3的形式. 本文介绍一下在windows 10 环境下如何使用这个工具: 1)首先要先安装好python3,可到官网下载https://www.python.org/ 2)使用Windows 命令提示符(cmd)打开2to3.

windows XP上实现python2.7.5和python3.4.3共存

windows XP上实现python2.7.5和python3.4.3共存过程记录: 1. 首先安装python2.7.5和python3.4.3,两个版本安装顺序不分前后; 2. 检查系统环境变量中是否存在以下四个变量,缺少则手动加入 c:\Python27; c:\Python27\Scripts; c:\Python34; c:\Python34\Scripts; (python安装路径为C:Python27则环境变量为c:\Python27;python安装路径为D:Python27则

相比于python2.6,python3.0的新特性。

这篇文章主要介绍了相比于python2.6,python3.0的新特性.更详细的介绍请参见python3.0的文档. Common Stumbling Blocks 本段简单的列出容易使人出错的变动. print语句被print()函数取代了,可以使用关键字参数来替代老的print特殊语法.例如: Old: print "The answer is", 2*2 New: print("The answer is", 2*2) Old: print x,       

如何把Python2的代码转换为Python3的代码

如何把Python2的代码转换为Python3的代码 注: 如果对于python2和python3不熟悉的,可以参考: [整理]总结Python2(Python 2.x版本)和Python3(Python 3.x版本)之间的区别 之前有机会接触到,将Python2的代码转换为Python3的代码. 经过一番折腾,大概有了基本概念了. 现在简要整理一下,关于如何将Python 2.x的代码,转换为Python 3.x的代码. 把Python 2.x的代码转换为Python 3.x代码的方法 1.自

python2.7升级到python3后,用pip进行安装时报Fatal error in launcher:Unbale to create process using`&quot;&quot;

解决:python2.7升级到python3后,用pip进行安装时报Fatal error in launcher:Unbale to create process using`"" 通过查资料查到:http://www.scriptscoop2.com/t/9cebc32c6ebc/python-fatal-error-in-launcher-unable-to-create-process-using-c-program-files.html 借鉴MiguelCldn 提供的方法,

Python学习教程_Python学习路线:Python3里你不知道的秘密特性

Python学习教程_Python学习路线:Python3里你不知道的秘密特性 概述 到2020年,Python2的官方维护期就要结束了,越来越多的Python项目从Python2切换到了Python3.其实在实际工作中,很多伙伴都还是在用Python2的思维写Python3的代码.给大家总结一下Python3一些新的更方便的特性!希望你们看完后也能高效率的编写代码 f-strings (3.6+) 在Python里面,我们经常使用format函数来格式化字符串,例如: user = "Jane

C#技术分享【PDF转换成图片——13种方案】(2013-07-25重新整理)

原文:C#技术分享[PDF转换成图片--13种方案](2013-07-25重新整理) 重要说明:本博已迁移到 石佳劼的博客,有疑问请到 文章新地址 留言!!! 写在最前面:为了节约大家时间,撸主把最常用的方法写在第一条,如果不满足您的需要,您可以继续往后看. 如果看完全文还是不能解决您的问题,欢迎加撸主的QQ群(274281457)进行讨论. 木有csdn分的童鞋,可以去github clone,地址:https://github.com/stone0090/OfficeTools.Pdf2Im

python2.7.X 升级至Python3.6.X

python2.7.X 升级至Python36.X 安装Python3 项目是在py3环境下进行编码的,正好Centos默认的py版本是2,我们还需要安装py3才能让程序run起来,在此之前,需要安装开发工具包,因为要编译安装Python[[email protected] ~]# yum -y group install "Development Tools" 安装Python的依赖包,不安装依赖可能安装完成后没有pip3 软件.[[email protected] ~]# yum

pycharm同时使用python2.7版本和python3.6版本

最近在看爬虫的专题,很多爬虫的教程是python2的,电脑上装的是3.6版本,而且python不向下兼容,这就很麻烦,最简单的print要加括号啊,等等.于是分享一个在windows环境下pycharm选择python版本的方法: 第一步:安装python2.7版本,为了方便管理,我们将python的两个版本放在同一目录下.python3.6的安装默认路径是C:\Users\用户名\AppData\Local\Programs\Python\,而python2.7的默认安装目录是C:\pytho