Things you are probably not using in python 3 but should -渣渣翻译- python3 好在哪里

原文地址:https://datawhatnow.com/things-you-are-probably-not-using-in-python-3-but-should/

 

Many people started switching their Python versions from 2 to 3 as a result of Python EOL. Unfortunately, most Python 3 I find still looks like Python 2, but with parentheses (even I am guilty of that in my code examples in previous posts – Introduction to web scraping with Python). Below, I show some examples of exciting features you can only use in Python 3 in the hopes that it will make solving your problems with Python easier.

All the examples are written in Python 3.7 and each feature contains the minimum required version of Python for that feature.

parentheses :n. 圆括号,插入语,插曲
guilty :adj. 有罪的;内疚的

 

因为python2终将停止维护,很多人已经在将python的版本由2转向3。但是我发现很多的python3的代码风格依然是python2,只是带上了括号(我很内疚,因为在我之前的一片文章中也犯过这样的错误-介绍使用python爬取web页面)。下面,我会展示一些只在python3中才有的特性的例子,希望可以轻松解决你在使用python的过程中遇到的问题。

所有的例子都是使用python3.7编写,而且每一种都包含该特性的python最低需求的版本。

f-strings (3.6+)

It is difficult to do anything without strings in any programming language and in order to stay sane, you want to have a structured way to work with strings. Most people using Python prefer using the format method.

sane :adj. 心智健全的; 神志正常的
structure :n. 结构, 构造,有结构的事物; 复杂的整体; 建筑物 vt. 组织; 安排; 构造; 制定

字符串方法f-strings(3.6+)

在任何编程语言中,如果没有字符串功能都会很困难,为了能够保持理智,你会想要一种结构化的方法来处理字符串。很多人在使用python的时候更愿意用fomat方法

 

    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.

 

Alongside of format, Python 3 offers a flexible way to do string interpolation via f-strings. The same code as above using f-strings looks like this:

Alongside :    adv. 靠着边, 沿着边     prep. (表示位置)在…旁边; 沿着…的边; 与…并排靠拢着     (表示比较)与…放在一起比较     (表示伴随)与…一起, 与…一道
flexible :adj. 灵活的;柔韧的;易弯曲的
interpolation :篡改,填写,插补

 

相比于format,python3通过f-strings提供了一种更灵活的方式操作字符串。相同的代码,在f-strings下如下所示:

    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.

 

Pathlib (3.4+)

f-strings are amazing, but some strings like file paths have their own libraries which make their manipulation even easier. Python 3 offers pathlib as a convenient abstraction for working with file paths. If you are not sure why you should be using pathlib, try reading this excellent post – Why you should be using pathlib – by Trey Hunner.

manipulation :    n. (熟练的)操作;操纵;控制     (对账目等的)伪造,篡改
convenient :adj. 方便的, 便利的, 合适的
abstraction :    n. 抽象,抽取 抽象化;抽象过程 抽象概念;抽象名称 抽象性,抽象的特征 出神;心不在焉 不切实际的想法,空想;幻想的事物 (艺术上的)抽象主义 <逻>抽象,抽离;抽离运符 <婉>偷窃
excellent :adj. 优秀的, 卓越的, 杰出的

 

f-string已经很棒了,但是有一些字符串,像文件路径,有专用的函数库用来处理会更方变和简单,python3提供了pathlib作为操作文件路径的一个很方便的抽象方法,如果你还不确定为什么要使用pathlib,请试一下读一读Trey Hunner的这篇文章-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 (3.5+)

Static vs dynamic typing is a spicy topic in software engineering and almost everyone has an opinion on it. I will let the reader decide when they should write types, but I think you should at least know that Python 3 supports type hints.

spicy :adj. 辛辣的;香的,多香料的;下流的
opinion :意见
hint :    n. 暗示;线索     vt. 暗示;示意     vi. 示意

 

静态和动态类型一直是软件工程师争论的热门话题,所有的人都有自己的主见,我会让读者自己决定是不是要标明类型,但是我认为你至少应该知道python3支持类型提示。

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

 

Enumerations (3.4+)

Python 3 supports an easy way to write enumerations through the Enum class. Enums are a convenient way to encapsulate lists of constants so they are not randomly located all over your code without much structure.

enumerations :应该是一种枚举类型
encapsulate :    vt. 装入胶囊     总结;扼要概括;囊括     adj. 有(胶)囊包着的
constant :    adj. 始终如一的, 恒久不变的     不断的, 连续发生的     忠实的, 忠诚的

 

python3可以通过Enum这个类简单的写出一个enumerations。Enums是一种用来封装列表的简单方法,它不会随机的分布在你的代码中,不会有太多的结构。

https://www.cnblogs.com/bdhk/p/7506691.html对Enum和auto有比较详细的解释

    from enum import Enum, auto
    class Monster(Enum):
        ZOMBIE = auto()
        WARRIOR = auto()
        BEAR = auto()
        
    print(Monster.ZOMBIE)
    # Monster.ZOMBIE

An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.

https://docs.python.org/3/library/enum.html
 
symbolic :adj. 象征的, 象征性的

 

枚举是一组集合,绑定了唯一常量值的变量名(成员)。 在枚举中,可以通过标识来比较成员,并且枚举本身可以迭代。
    for monster in Monster:
        print(monster)
    # Monster.ZOMBIE
    # Monster.WARRIOR
    # Monster.BEAR

 

Built-in LRU cache (3.2+)

Caches are present in almost any horizontal slice of the software and hardware we use today. Python 3 makes using them very simple by exposing an LRU (Least Recently Used) cache as a decorator called lru_cache.

Below is a simple Fibonacci function that we know will benefit from caching because it does the same work multiple times through a recursion.

Built-in :内置
LRU :内存管理的一种页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU,Least recently used,最近最少使用
present :    vt. 呈现;介绍;提出;赠送     vi. 举枪瞄准     adj. 出席的;现在的     n. 现在;礼物;瞄准
horizontal :adj. 水平的, 与地平线平行的
exposing :
n. 遗弃;露体;陈列v. 展览;揭露;遭遇(expose的ing形式)
recursion :递归式

 

如今,高速缓存已经存在于我们使用的硬件和软件的各个层面。Python3可以简单的使用他们,通过调用装饰器-lru_cache来展示一个LRU cache。(觉得翻译的不给力,尤其是exposing)

下面是一个简单的Fibonacci function(斐波那契函数),我们知道它将从缓存中受益,因为它通过递归多次执行相同的工作。

    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

Now we can use the lru_cache to optimize it (this optimization technique is called memoization). The execution time goes down from seconds to nanoseconds.

optimize :vt. 使最优化,使完善;vi. 优化;持乐观态度
memoization :记忆化

 

现在,我们可以使用lru_cache来优化它(这种优化技术称为memoization)。执行时间从几秒到减少到几纳秒。

推荐阅读:https://www.cnblogs.com/cuiyubo/p/8375859.html

    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: 6.866455078125e-05s

Extended iterable unpacking (3.0+)

对可迭代对象的扩展解包

I will let the code speak here (docs).

我将让代码自己说话。

    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 classes (3.7+)

Python 3 introduces data classes which do not have many restrictions and can be used to reduce boilerplate code because the decorator auto-generates special methods, such as __init__() and __repr()__. From the official proposal, they are described as “mutable named tuples with defaults”.

introduce :vt. 介绍, 引见 提出, 提出供讨论 引进, 采用 将…放[插]入
restrictions :约束,限制
boilerplate :样板文件
generates :vt. 使形成;生殖;发生
proposal :提议,建议,求婚
mutable :adj. 易变的,性情不定的

 

Python 3引入了数据类,这些数据类没有太多限制,并且可以用来减少样板代码,因为装饰器会自动生成特殊的方法,比如__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>

The same implementation of Armor using data classes.

implementation :n. 贯彻,执行

 

使用data classes 执行相同的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)
    armor.power()
    # 10.4
    print(armor)
    # Armor(armor=5.2, description='Common armor.', level=2)   

注:最后打印的对象的形式,是我读到这里觉得最棒的东西,不再像之前的,只是一个关于对象的归属信息和一个内存编码的东西。这就是我需要的。不用再频繁的使用__dict__

Implicit namespace packages (3.3+)

隐含名称空间的包结构

One way to structure Python code is in packages (folders with an __init__.py file). The example below is given by the official Python documentation.

Implicit :adj. 暗示的;盲从的;含蓄的
structure :n. 结构, 构造 有结构的事物; 复杂的整体; 建筑物 vt. 组织; 安排; 构造; 制定
folders :n. 文件夹,方法;折页,档案夹

 

一种构造python代码目录结构的方式是用包(在文件夹中放一个__init__.py文件)。下面是Python官方文档给出的例子

    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
                  ...

In Python 2, every folder above had to have an __init__.py file which turned that folder into a Python package. In Python 3, with the introduction of Implicit Namespace Packages, these files are no longer required.

在python2中,每一个文件夹下面都有一个__init__.py文件,作为将文件夹转换成一个包文件。在python3中,随着Implicit Namespace Packages的引入,不再需要这些文件了。

    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
                  ...

 

EDIT: as some people have said, this is not as simple as I pointed it out in this section, from the official PEP 420 Specification__init__.py is still required for regular packages, dropping it from the folder structure will turn it into a native namespace package which comes with additional restrictions, the official docs on native namespace packages show a great example of this, as well as naming all the restrictions.

regular :    adj. 整齐的;定期的;有规律的;合格的     n. 正式队员;常客;中坚分子     adv. 经常地;定期地
additional :adj. 增加的, 额外的, 另外的

 

编者:正如有些人说的那样,并不像本章节描述的那样简单,官方文档PEP 420 Specification指出- 常规包仍然需要__init__.py ,将它从结构中删除后,会把包变成一个被限制的native namespace package(本地命名空间),官方文档中对native namespace package(本地命名空间)列举了相关例子,以及对命名的所有限制。

Closing note

Like almost any list on the internet, this one is not complete. I hope this post has shown you at least one Python 3 functionality you did not know existed before, and that it will help you write cleaner and more intuitive code. As always, all the code can be found on GitHub.

intuitive :adj. 有直觉力的;凭直觉获知的

 

就像互联网上的所有列表一样,这个列表并不完整。 我希望这篇文章向您展示了至少一个你以前不知道的Python 3功能,并且它将帮助您编写更清晰,更直观的代码。 与往常一样,所有代码都可以在GitHub上找到。

 

 

 

posted @ 2019-06-28 09:31  游小刀  阅读(321)  评论(0编辑  收藏  举报
levels of contents