「python 技巧」譯-python 3 值得嘗試的一些技巧

原文:datawhatnow.com/things-you-…html

做者:Vinko Kodžomanpython

時間:May 6, 2019web

譯者:DeanWu編程

Python2中止維護日期(Python EOL)發佈以來,愈來愈多的人開始從python2轉爲python3。可是,我發現大多數Python3代碼看起來仍是像Python3。在我之前博文(Python web 抓取簡介)中的實例也是如此,我爲此感到抱歉。api

下面,我將展現一些使人興奮的功能實例,他們只能在Python3的環境下使用,他們能夠幫助你更輕鬆的解決問題。緩存

全部示例都是用Python 3.7編寫的,每一個實例都包含該功能所需的最低Python版本。app

f-strings(3.6+)

在任何一門編程語言中,若沒有字符串類型,咱們處理問題是很是困難的。爲了保持程序的穩定性,你但願有一種結構化的方式來處理字符串。大多數使用Python的人更喜歡使用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-strings重寫上述代碼,以下:ide

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是驚人的,可是像文件路徑這樣的字符串有本身的庫,這使得處理起文件路徑來更加容易。Python 3提供了pathlib做爲處理文件路徑的便捷抽象庫。可參閱另外一篇文章,來了解 爲何您應該使用pathlib - by Trey Hunner函數

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

靜態與動態類型是軟件工程中的一個熱門話題,幾乎每一個人都對它有本身的見解。我不會干涉讀者什麼時候應該使用何種類型,但我認爲你至少應該知道Python 3支持type hints

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支持經過繼承Enum類來實現枚舉。枚舉是一種封裝常量列表的便捷方式,它具備必定的結構組織在一塊兒,而不會散落在代碼的各個角落。

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. 枚舉是一組綁定到惟一常量值的符號名稱(成員)。在枚舉中,能夠經過標識來比較成員,而且能夠迭代枚舉自己。 docs.python.org/3/library/e…

for monster in Monster:
    print(monster)
# Monster.ZOMBIE
# Monster.WARRIOR
# Monster.BEAR
複製代碼

Built-in LRU cache(內建LRU緩存) (3.2+)

咱們今天使用的軟件和硬件,在不少地方都使用了高速緩存。Python 3經過將LRU(最近最少使用)緩存暴露爲名爲lru_cache的裝飾器,使得使用它們變得很是簡單。

下面是一個簡單的Fibonacci函數,他屢次遞歸都執行相同的邏輯,咱們可使用緩存來優化它。

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
複製代碼

如今咱們可使用它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: 6.866455078125e-05s
複製代碼

Extended iterable unpacking (可迭代對象的擴展使用)(3.0+)

可直接在這裏查看代碼說明 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引入了 data class,這些數據類沒有太多限制,可用來減小咱們的初始化代碼,由於裝飾器會自動生成特殊方法,例如__init__()和__repr()__。在官方提案中,它們被描述爲「具備默認值的可變命名元組(mutable named tuples with default)」。

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)
armor.power()
# 10.4
print(armor)
# Armor(armor=5.2, description='Common armor.', level=2)
複製代碼

總結

想互聯網上的其餘教程列表同樣,本列表並不完整。我但願這篇文章向您展現了至少一個您之前不知道的Python 3功能,而且它將幫助您編寫更清晰,更直觀的代碼。

相關文章
相關標籤/搜索