本文經機器之心(微信公眾號:almosthuman2014)授權轉載,禁止二次轉載
選自FreeCodeCamp作者:Peter Gleeson
機器之心編譯,參與:路、王淑婷
原文連結:https://medium.freecodecamp.org/an-a-z-of-useful-python-tricks-b467524ee747
被人工智慧捧紅的 Python 已是一種發展完善且非常多樣化的語言,其中肯定有一些你尚未發現的功能。本文或許能夠讓你學到一些新技巧。
Python 是世界上最流行、熱門的程式語言之一,原因很多,比如:
-
易於學習
-
超高的通用性
-
具備大量模組和庫
本文將分享一些使用 Python 的技巧,順序按照 A-Z 排列。
all or any
Python 非常受歡迎的原因之一是其可讀性和表達性。
人們還經常把 Python 笑稱為「可執行偽碼(executable pseudocode)」。但是,當你可以編寫這樣的程式碼時,很難去反駁這種言論:
x = [True, True, False]
if any(x):
print("At least one True")
if all(x):
print("Not one False")
if any(x) and not all(x):
print("At least one True and one False")
bashplotlib
想在控制臺中繪圖嗎?
$ pip install bashplotlib
使用上面的行,即可在控制臺中繪圖。
collections
Python 有一些很棒的預設資料型別,但有時候它們可能不會盡如你意。
不過,Python 標準庫提供了 collections 模組。這個方便的附加元件可以為你提供更多資料型別。
collections 模組:https://docs.python.org/3/library/collections.html
from collections import OrderedDict, Counter
# Remembers the order the keys are added!
x = OrderedDict(a=1, b=2, c=3)
# Counts the frequency of each character
y = Counter("Hello World!")
dir
你是否想過如何檢視 Python 物件內部及其具有哪些屬性?
輸入以下命令列:
>>> dir()
>>> dir("Hello World")
>>> dir(dir)
當以互動方式執行 Python 時,這可能是一個非常有用的功能,並且可以動態地探索你正在使用的物件和模組。
想要瞭解更多,點這裡:https://docs.python.org/3/library/functions.html#dir
emoji
是的,真的有。請點選這裡:https://pypi.org/project/emoji/
$ pip install emoji
別以為我不知道你會偷偷試它→→
from emoji import emojize
print(emojize(":thumbs_up:"))
?
from __future__ import
Python 流行的一個結果是,總有新版本正在開發中。新版本意味著新功能——除非你的版本已經過時。
不過,別擔心。__ future__模組允許使用者匯入新版 Python 的功能。這簡直就像時間旅行,或者魔法什麼的。
__ future__模組:https://docs.python.org/2/library/*future*.html
from __future__ import print_function
print("Hello World!")
geopy
地理(Geography)對於程式員來說可能是一個具有挑戰性的領域。但是 geopy 模組讓它變得異常簡單。
geopy 模組:https://geopy.readthedocs.io/en/latest/
$ pip install geopy
它透過抽取一系列不同地理編碼服務的 API 來工作,使使用者獲取一個地方的完整街道地址、緯度、經度,甚至海拔高度。
另外一個有用的功能是距離:它可以用你喜歡的度量單位計算出兩個位置之間的距離。
from geopy import GoogleV3
place = "221b Baker Street, London"
location = GoogleV3().geocode(place)
print(location.address)
print(location.location)
howdoi
陷入編碼問題,卻不記得以前見過的解決方案?需要檢查 StackOverflow,但不想離開終端?
那麼你需要這個有用的命令列工具:https://github.com/gleitz/howdoi。
$ pip install howdoi
無論你有什麼問題都可以問它,它會儘力回答。
$ howdoi vertical align css
$ howdoi for loop in java
$ howdoi undo commits in git
但是請註意——它會從 StackOverflow 的最高票答案中抓取程式碼。也就是說它提供的資訊並非總是有用……
$ howdoi exit vim
inspect
Python 的 inspect 模組非常有助於理解問題背後的詳情。你甚至可以在 inspect 模組上呼叫其方法!
inspect 模組:https://docs.python.org/3/library/inspect.html
下麵的程式碼示例使用 inspect.getsource() 列印自己的原始碼。它還使用 inspect.getmodule() 列印定義它的模組。
最後一行程式碼打印出自己的行號。
import inspect
print(inspect.getsource(inspect.getsource))
print(inspect.getmodule(inspect.getmodule))
print(inspect.currentframe().f_lineno)
當然,除了這些瑣碎的用途之外,inspect 模組還能幫助你理解程式碼正在做的事。你還可以用它編寫自檔案化程式碼。
Jedi
Jedi 庫是一個自動完成和程式碼分析的庫。它使程式碼編寫變得更快、效果更高。
除非你正在開發自己的 IDE,否則你肯定會對使用 Jedi 庫作為編輯外掛很感興趣。
Jedi:https://jedi.readthedocs.io/en/latest/docs/usage.html
你可能已經在使用 Jedi 了。IPython 專案就使用 Jedi 實現程式碼自動完成功能。
**kwargs
學習任何語言時都會遇到很多里程碑。對於 Python 來說,理解神秘的**kwargs 語法可能算是其中之一。
詞典物件前面的雙星號可以讓你把該詞典的內容作為命名引數輸入到函式中。
詞典的秘鑰是引數名,值是傳遞給函式的值。你甚至不需要稱它為 kwargs!
dictionary = {"a": 1, "b": 2}
def someFunction(a, b):
print(a + b)
return
# these do the same thing:
someFunction(**dictionary)
someFunction(a=1, b=2)
當你想編寫能夠處理事先未定義的命名引數的函式時,這個很有用。
串列推導式(List comprehensions)
我最喜歡 Python 程式設計的原因之一是它的串列推導式(https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions)。
這些運算式使得編寫乾凈易讀的程式碼變得很容易,那些程式碼讀起來幾乎像自然語言一樣。
關於它們的更多使用資訊請檢視:https://www.learnpython.org/en/List_Comprehensions
numbers = [1,2,3,4,5,6,7]
evens = [x for x in numbers if x % 2 is 0]
odds = [y for y in numbers if y not in evens]
cities = ['London', 'Dublin', 'Oslo']
def visit(city):
print("Welcome to "+city)
for city in cities:
visit(city)
map
Python 透過許多內建功能支援函式式程式設計。map() 函式是最有用的函式之一——特別是當它與 lambda 函式結合使用時。
lambda 函式:https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions
x = [1, 2, 3]
y = map(lambda x : x + 1 , x)
# prints out [2,3,4]
print(list(y))
在上面的例子中,map() 將一個簡單的 lambda 函式應用於 x 中的每個元素。它傳回一個 map 物件,該物件可以被轉換成可迭代的物件,如串列或元組。
newspaper3k
如果你之前沒有見過它,那麼我建議你先檢視:https://pypi.org/project/newspaper3k/。
它可以幫助你從大量頂級國際出版物中檢索到新聞文章和相關元資料。你可以檢索影象、文字和作者名。
它還有一些內建的 NLP 功能。
地址:https://newspaper.readthedocs.io/en/latest/user_guide/quickstart.html#performing-nlp-on-an-article
如果你想在下一個專案中使用 BeautifulSoup 或其它 DIY 網頁抓取庫,那麼不如使用$ pip install newspaper3k,既省時又省事,何樂而不為呢?
運運算元多載(Operator overloading)
Python 支援運運算元多載。
它實際上是一個簡單的概念。你有沒有想過為什麼 Python 允許使用者使用 + 運運算元來將數字相加,並級聯字串?這就是運運算元多載在發揮作用。
你可以使用 Python 的標準運運算元號來定義物件,這樣你可以在與這些物件相關的語境中使用它們。
class Thing:
def __init__(self, value):
self.__value = value
def __gt__(self, other):
return self.__value > other.__value
def __lt__(self, other):
return self.__value something = Thing(100)
nothing = Thing(0)
# True
something > nothing
# False
something # Error
something + nothing
pprint
Python 的預設 print 函式就可以實現列印功能。但如果嘗試列印較大的巢狀物件,就會發現列印結果很醜。
這時 Python 標準庫的 pretty printer 模組就可以發揮作用了。該模組可以將複雜的結構化物件以一種易讀的格式打印出來。
pretty printer 模組:https://docs.python.org/3/library/pprint.html
Python 開發者的必備技能之一就是處理複雜的資料結構。
import requests
import pprint
url = 'https://randomuser.me/api/?results=1'
users = requests.get(url).json()
pprint.pprint(users)
Queue
Python 支援多執行緒,而這是由 Python 標準庫的 Queue 模組支援的。
該模組允許使用者實現佇列(queue)資料結構。佇列資料結構允許使用者根據特定的規則新增和檢索條目。
『First in, first out』 (FIFO) 佇列允許使用者按照物件被新增的順序來檢索物件。『Last in, first out』 (LIFO) 佇列允許使用者首先訪問最新新增的物件。
最後,優先順序佇列(priority queue)允許使用者根據物件對應的優先順序類別來檢索物件。
如何使用 queue 在 Python 中實現多執行緒程式設計,示例詳見:https://www.tutorialspoint.com/python3/python_multithreading.htm。
__repr__
在 Python 中定義一個類別或物件時,以「官方」方式將物件表示為字串很有用。例如:
>>> file = open('file.txt', 'r')
>>> print(file)
'file.txt', mode 'r' at 0x10d30aaf0>
這使程式碼 debug 變得簡單很多。將字串新增到類別定義,如下所示:
class someClass:
def __repr__(self):
return "<some description here>"
someInstance = someClass()
# prints
print(someInstance)
sh
Python 是一種偉大的指令碼語言,不過有時使用標準 os 和 subprocess 庫會有點棘手。
sh 庫提供了一種不錯的替代方案。
sh 庫:http://amoffat.github.io/sh/
該庫允許使用者像使用普通函式一樣呼叫任意程式,這對自動化工作流和任務非常有用。
from sh import *
sh.pwd()
sh.mkdir('new_folder')
sh.touch('new_file.txt')
sh.whoami()
sh.echo('This is great!')
型別提示(Type hints)
Python 是動態語言。在定義變數、函式、類別等時無需指定資料型別。
這有利於縮短開發週期。但是,簡單的型別錯誤(typing issue)導致的執行時錯誤真的太煩了。
從 Python 3.5 版本開始,使用者可以選擇在定義函式時開啟型別提示。
def addTwo(x : Int) -> Int:
return x + 2
你還可以定義型別別名:
from typing import List
Vector = List[float]
Matrix = List[Vector]
def addMatrix(a : Matrix, b : Matrix) -> Matrix:
result = []
for i,row in enumerate(a):
result_row =[]
for j, col in enumerate(row):
result_row += [a[i][j] + b[i][j]]
result += [result_row]
return result
x = [[1.0, 0.0], [0.0, 1.0]]
y = [[2.0, 1.0], [0.0, -2.0]]
z = addMatrix(x, y)
儘管非強制,但型別註釋可以使程式碼更易理解。
它們還允許你在執行之前使用型別檢查工具捕捉 TypeError。在進行大型複雜專案時執行此類操作是值得的。
uuid
生成通用唯一識別符號(Universally Unique ID,UUID)的一種快速簡單方法就是使用 Python 標準庫的 uuid 模組。
uuid 模組:https://docs.python.org/3/library/uuid.html
import uuid
user_id = uuid.uuid4()
print(user_id)
這建立了一個隨機化後的 128 位元數字,該數字幾乎必然是唯一的。
事實上,可以生成 2¹²²可能的 UUID。這個數字超過了 5,000,000,000,000,000,000,000,000,000,000,000,000。
在給定集合中找出重覆數字的可能性極低。即使有一萬億 UUID,重覆數字存在的機率也遠遠低於十億分之一。
虛擬環境(Virtual environment)
這可能是 Python 中我最喜歡的事物了。
你可能同時處理多個 Python 專案。不幸的是,有時候兩個專案依賴於相同依賴項的不同版本。那你要安裝哪個版本呢?
幸運的是,Python 支援虛擬環境,這使得使用者能夠充分利用兩種環境。見下列行:
python -m venv my-project
source my-project/bin/activate
pip install all-the-modules
現在你在一臺機器上具備獨立的多個 Python 版本了。問題解決!
wikipedia
Wikipedia 擁有一個很棒的 API,允許使用者以程式設計方式訪問巨大體量的免費知識和資訊。
wikipedia 模組使得訪問該 API 非常便捷。
Wikipedia 模組:https://wikipedia.readthedocs.io/en/latest/quickstart.html
import wikipedia
result = wikipedia.page('freeCodeCamp')
print(result.summary)
for link in result.links:
print(link)
和真實的維基百科網站類似,該模組支援多種語言、頁面消歧、隨機頁面檢索,甚至還具備 donate() 方法。
xkcd
humour 是 Python 語言的一個關鍵特徵,其名稱來自英國喜劇片《蒙提·派森的飛行馬戲團》(Monty Python and the Flying Circus)。Python 的很多官方檔案取用了該喜劇片最著名的劇情。
幽默感並不限於檔案。試著執行下列行:
import antigravity
將開啟 xkcd 畫的 Python 漫畫。不要改變這一點,Python。不要改變。
YAML
YAML 代表 『YAML Ain』t Markup Language』。它是一種資料格式語言,是 JSON 的超集。
與 JSON 不同,它可以儲存更複雜的物件並取用自己的元素。你還可以編寫註釋,使其尤其適用於編寫配置檔案。
PyYAML 模組(https://pyyaml.org/wiki/PyYAMLDocumentation)可以讓你在 Python 中使用 YAML。安裝:
$ pip install pyyaml
然後匯入到專案中:
import yaml
PyYAML 使你能夠儲存任何資料型別的 Python 物件,以及任何使用者定義類別的實體。
zip
給你支最後一招,非常酷。還在用兩個串列來組成一部詞典嗎?
keys = ['a', 'b', 'c']
vals = [1, 2, 3]
zipped = dict(zip(keys, vals))
zip() 內建函式使用多個可迭代物件作為輸入並傳回元組串列。每個元組按位置索引對輸入物件的元素進行分組。
你也可以透過呼叫*zip() 來「解壓」物件。
●編號500,輸入編號直達本文
●輸入m獲取文章目錄
Web開發
更多推薦《18個技術類微信公眾號》
涵蓋:程式人生、演演算法與資料結構、駭客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。