Python2 倒计时,还不快来掌握 Python3 酷炫的新特性? | 原力计划
以下文章来源于云爬虫技术研究笔记 ,作者Lateautumn4lin
作者 | 云爬虫技术研究笔记
责编 | 郭芮
出品 | CSDN 博客
Python2.7正式停止维护时间 2020年1月1日,距今还有1个多月
Python3.8正式开始发布时间 2019年10月14日,距今1个多月
格式化字符串 f-string(最低 Python 版本为 3.6)
print("My name is %s" % ('phithon', ))
print("My name is %(name)s" % {'name':'phithon'})
print("My name is {}".format("bob"))
print("My name is {name}".format(name="bob"))
name="bob"
print(f"My name is {name}")
路径管理库 Pathlib(最低 Python 版本为 3.4)
from glob import glob
file_contents = []
for filename in glob('**/*.py', recursive=True):
with open(filename) as python_file:
file_contents.append(python_file.read())
from pathlib import Path
file_contents = [
path.read_text()
for path in Path.cwd().rglob('*.py')
]s')
类型提示 Type hinting(最低 Python 版本为 3.5)
编程语言有很多类型,静态编译型语言和动态解释型语言的对比是软件工程中一个热门的话题,几乎每个人对此有自己的看法。在静态语言中类型标注无疑是让人又爱又恨,爱的是编译速度加快,团队合作中准确了解函数方法的入参类型,恨的是Coding时极其繁琐的标注。不过,标注这种极其符合团队文化的操作还是在Python3中被引入,并且很快得到了人们的喜爱。
def print_yes_or_no(codition: str) -> bool:
pass
枚举(最低 Python 版本为 3.4)
#利用type自建类的骚操作
def enum(**enums):
return type('Enum', (), enums)
Numbers = enum(ONE=1, TWO=2, THREE='three')
# Numbers.ONE == 1, Numbers.TWO == 2 and Numbers.THREE == 'three'
#利用type自建类的骚操作升级版
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
Numbers = enum('ZERO', 'ONE', 'TWO')
# Numbers.ZERO == 0 and Numbers.ONE == 1
#有带值到名称映射的
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
reverse = dict((value, key) for key, value in enums.iteritems())
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)
# Numbers.reverse_mapping['three'] == 'THREE'
# 更有甚者,利用namedtuple实现的
from collections import namedtuple
def enum(*keys):
return namedtuple('Enum', keys)(*keys)
MyEnum = enum('FOO', 'BAR', 'BAZ')
# 带字符数字映射的,像C/C++
def enum(*keys):
return namedtuple('Enum', keys)(*range(len(keys)))
# 带字典映射的,可以映射出各种类型,不局限于数字
def enum(**kwargs):
return namedtuple('Enum', kwargs.keys())(*kwargs.values())
from enum import Enum, auto
class Monster(Enum):
ZOMBIE = auto()
WARRIOR = auto()
BEAR = auto()
print(Monster.ZOMBIE)
for i in Monster:
print(i)
原生 LRU 缓存(最低 Python 版本为 3.2)
import time
def fib(number: int) -> int:
if number == 0:
return 0
if number == 1:
return 1
return fib(number-1) + fib(number-2)
start = time.time()
fib(40)
print(f'Duration: {time.time() - start}s')
# Duration: 30.684099674224854s
from functools import lru_cache
def fib_memoization(number: int) -> int:
if number == 0:
return 0
if number == 1:
return 1
return fib_memoization(number-1) + fib_memoization(number-2)
start = time.time()
fib_memoization(40)
print(f'Duration: {time.time() - start}s')
# Duration: 6.866455078125e-05s
def f(x):
...
def f(x):
...
扩展的可迭代对象解包(最低 Python 版本为 3.0)
# Python 3.4 中 print 函数 不允许多个 * 操作
> print(*[1,2,3], *[3,4])
File "<stdin>", line 1
print(*[1,2,3], *[3,4])
^
SyntaxError: invalid syntax
>
# 再来看看 python3.5以上版本
# 可以使用任意多个解包操作
> print(*[1], *[2], 3)
1 2 3
> *range(4), 4
(0, 1, 2, 3, 4)
> [*range(4), 4]
[0, 1, 2, 3, 4]
> {*range(4), 4}
{0, 1, 2, 3, 4}
> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}
Data class 装饰器(最低 Python 版本为 3.7)
from dataclasses import dataclass
class DataClassCard:
rank: str
suit: str
#生成实例
queen_of_hearts = DataClassCard('Q', 'Hearts')
print(queen_of_hearts.rank)
print(queen_of_hearts)
print(queen_of_hearts == DataClassCard('Q', 'Hearts'))
#Q
#DataClassCard(rank='Q', suit='Hearts')
#True
class RegularCard
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
queen_of_hearts = RegularCard('Q', 'Hearts')
print(queen_of_hearts.rank)
print(queen_of_hearts)
print(queen_of_hearts == RegularCard('Q', 'Hearts'))
#'Q'
#<__main__.RegularCard object at 0x7fb6eee35d30>
#False
虽然这种写法并没有使用更多的代码量,但是我们很容易看到为了初始化,仅仅只是为了初始化一个对象,rank和suit已经重复了三次。此外,如果你试图使用这个RegularCard类,你会注意到对象的表示不是很具描述性,并且已有的类与新声明的类是无法比较是否相同的。因为每次声明都会使用一个新的内存地址,而“==”不止比较类存储的信息,还比较内存地址是否相同。
class RegularCard(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __repr__(self):
#可以将类的信息打印出来
return (f'{self.__class__.__name__}'
f'(rank={self.rank!r}, suit={self.suit!r})')
#大家可以试着将“!r”去掉或者将其中的r改变为s或a,看看输出结果会有什么变化
#conversion character: expected 's', 'r', or 'a'
def __eq__(self, other):
#可以比较类是否相同(不考虑内存地址)
if other.__class__ is not self.__class__:
return NotImplemented
return (self.rank, self.suit) == (other.rank, other.suit)
隐式命名空间包(最低 Python 版本为 3.3)
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py .
..
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
equalizer.py
vocoder.py
karaoke.py
...
声明:本文为CSDN博主「云爬虫技术研究笔记」的原创文章,版权归作者所有。
一身的本领得不施展?
优质的文章得不到曝光?
别担心,
即刻起,CSDN 将为你带来创新创造创变展现的大舞台,
扫描下方二维码,欢迎加入 CSDN 「原力计划」!
热 文 推 荐