从 3.0 到 3.8,Python 3 已经更新了一波又一波,但似乎我们用起来和 2.7 没有太大区别?以前该怎么写 2.7 的代码现在就怎么写,只不过少数表达方式变了而已。在这篇文章中,作者介绍了 3.0 以来真正 Amazing 的新函数与新方法,也许这些方法我们都不太熟,但它们确实在实践中非常重要。

一、格式化字符串f-string

在任何的编程语言中,不使用字符串都是寸步难行的。而为了保持思路清晰,你会希望有一种结构化的方法来处理字符串。Python中格式化字符串目前有四种方法,大家可以参见我的这篇博客:https://www.cnblogs.com/zhangyafei/p/9837602.html

大多数使用 Python 的人会偏向于使用「format」方法。

# format
user = "Jane Doe"
action = "buy"
log_message = 'User {} has logged in and did an action {}.'.format(
user,
action
)
print(log_message)
# User Jane Doe has logged in and did an action buy.

除了「format」,Python 3 还提供了一种通过「f-string」进行字符串插入的灵活方法。使用「f-string」编写的与上面功能相同的代码是这样的:

# f-string
user = "Jane Doe"
action = "buy"
log_message = f'User {user} has logged in and did an action {action}.'
print(log_message)
# User Jane Doe has logged in and did an action buy.

相比于常见的字符串格式符 %s 或 format 方法,f-strings 直接在占位符中插入变量显得更加方便,也更好理解。

二、路径管理库 Pathlib(最低 Python 版本为 3.4)  

  f-string 非常强大,但是有些像文件路径这样的字符串有他们自己的库,这些库使得对它们的操作更加容易。Python 3 提供了一种处理文件路径的抽象库「pathlib」。如果你不知道为什么应该使用 pathlib,请参阅下面这篇 Trey Hunner 编写的炒鸡棒的博文:「https://treyhunner.com/2018/12/why-you-should-be-using-pathlib/」

from pathlib import Path

root = Path('post_sub_folder')
print(root)
# post_sub_folder path = root / 'happy_user' # Make the path absolute
print(path.resolve())
# /home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_user

如上所示,我们可以直接对路径的字符串进行「/」操作,并在绝对与相对地址间做转换。

三、类型提示 Type hinting(最低 Python 版本为 3.5)

  静态和动态类型是软件工程中一个热门的话题,几乎每个人 对此有自己的看法。读者应该自己决定何时应该编写何种类型,因此你至少需要知道 Python 3 是支持类型提示的。

def sentence_has_animal(sentence: str) -> bool:
return "animal" in sentence sentence_has_animal("Donald had a farm without animals")
# True

四、枚举(最低 Python 版本为 3.4)

Python 3 支持通过「Enum」类编写枚举的简单方法。枚举是一种封装常量列表的便捷方法,因此这些列表不会在结构性不强的情况下随机分布在代码中。

from enum import Enum, auto

class Monster(Enum):
ZOMBIE = auto()
WARRIOR = auto()
BEAR = auto() print(Monster.ZOMBIE)
# Monster.ZOMBIE

枚举是符号名称(成员)的集合,这些符号名称与唯一的常量值绑定在一起。在枚举中,可以通过标识对成员进行比较操作,枚举本身也可以被遍历。

参考:https://docs.python.org/3/library/enum.html

for monster in Monster:
print(monster) # Monster.ZOMBIE
# Monster.WARRIOR
# Monster.BEAR

五、原生 LRU 缓存(最低 Python 版本为 3.2)

  目前,几乎所有层面上的软件和硬件中都需要缓存。Python 3 将 LRU(最近最少使用算法)缓存作为一个名为「lru_cache」的装饰器,使得对缓存的使用非常简单。

  下面是一个简单的斐波那契函数,我们知道使用缓存将有助于该函数的计算,因为它会通过递归多次执行相同的工作。

 

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: 59.59635329246521s

现在,我们可以使用「lru_cache」来优化它(这种优化技术被称为「memoization」)。通过这种优化,我们将执行时间从几十秒降低到了几纳秒。

from functools import lru_cache

@lru_cache(maxsize=512)
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: 0.0s

六、扩展的可迭代对象解包(最低 Python 版本为 3.0)

对于这个特性,代码就说明了一切。

参考:https://www.python.org/dev/peps/pep-3132/

head, *body, tail = range(5)
print(head, body, tail)
# 0 [1, 2, 3] 4 py, filename, *cmds = "python3.7 script.py -n 5 -l 15".split()
print(py)
print(filename)
print(cmds)
# python3.7
# script.py
# ['-n', '5', '-l', '15'] first, _, third, *_ = range(10)
print(first, third)
# 0 2

七、Data class 装饰器(最低 Python 版本为 3.7)

Python 3 引入了「data class」,它们没有太多的限制,可以用来减少对样板代码的使用,因为装饰器会自动生成诸如「__init__()」和「__repr()__」这样的特殊方法。在官方的文档中,它们被描述为「带有缺省值的可变命名元组」。

class Armor:

    def __init__(self, armor: float, description: str, level: int = 1):
self.armor = armor
self.level = level
self.description = description def power(self) -> float:
return self.armor * self.level armor = Armor(5.2, "Common armor.", 2)
armor.power()
# 10.4 print(armor)
# <__main__.Armor object at 0x7fc4800e2cf8>

使用「Data class」实现相同的 Armor 类。

from dataclasses import dataclass

@dataclass
class Armor:
armor: float
description: str
level: int = 1 def power(self) -> float:
return self.armor * self.level armor = Armor(5.2, "Common armor.", 2)
result = armor.power() print(armor)
print(result) # Armor(armor=5.2, description='Common armor.', level=2)
# 10.4

最新文章

  1. 【转】随机函数 rand() srand() 以及seed的原理
  2. Spring+Struts2/Hibernate 学习笔记
  3. Ext JS 6 新特性和工具
  4. jQuery 的 ajax
  5. zsh配置文件
  6. JDBC学习笔记(7)——事务的隔离级别&amp;批量处理
  7. JDBCTemplate.java
  8. iis7.0/8.0rewrite规则
  9. Linux中TCP wrapper的使用
  10. 世纪互联、微软Azure与无穷小微积分
  11. 应用控制台应用程序开发批量导入EXEL程序。
  12. ReactiveSwift源码解析(十二) MutableProperty基本代码实现
  13. Redux Counter example
  14. DBUtils——handler
  15. 编程,计算data段中的第一组数据的3次方,结果保存在后面一组dword单元中
  16. Java如何显示工作日(周一至周五)的名称?
  17. autoreleasepool 自动释放池的理解
  18. Java or Python?测试开发工程师如何选择合适的编程语言?
  19. JS如何将变量作为一个对象的Key
  20. 【bzoj3196】Tyvj 1730 二逼平衡树 线段树套Treap

热门文章

  1. Pagination.js + Sqlite web系统分页
  2. hibernate多对多单向(双向)关系映射
  3. 用工具堆砌的DevOps 幻觉
  4. Jenkins分布式与并行
  5. 搞IT的应届生如何写好简历?
  6. vue在某页面监听键盘输入事件
  7. 主要视图展示(Project)
  8. IM服务器:编写一个健壮的服务器程序需要考虑哪些问题
  9. Spring整合redis实现key过期事件监听
  10. 【LeetCode】1171. Remove Zero Sum Consecutive Nodes from Linked List 解题报告 (C++)