摘要:常規(guī)的使用來統(tǒng)計(jì)一段代碼運(yùn)行時(shí)間的例子輸出結(jié)果總結(jié)其實(shí)是一門特別人性化的語言,但凡在工程中經(jīng)常遇到的問題,處理起來比較棘手的模式基本都有對(duì)應(yīng)的比較優(yōu)雅的解決方案。
python的高級(jí)特性 名詞與翻譯對(duì)照表
generator 生成器
iterator 迭代器
collection 集合
pack/unpack 打包/解包
decorator 裝飾器
context manager 上下文管理器
本篇文章重點(diǎn)介紹以下內(nèi)容python語言的一些高階用法主要有以下幾個(gè)特性:
generators生成器用法
collections包常見用法
itertools包常見用法
packing/unpacking封包/解包特性
Decorators裝飾器
Context Managers上下文管理期
以上幾個(gè)特性我會(huì)針對(duì)應(yīng)用場(chǎng)景,使用注意事項(xiàng),應(yīng)用舉例幾個(gè)維度分別進(jìn)行講解,如果有同學(xué)對(duì)某個(gè)特性特別熟悉則可以直接跳過。
generators生成器用法generator一般用來產(chǎn)生序列類型的值得對(duì)象,一般都可以在for循環(huán)中迭代,也可以通過next方法調(diào)用,生成器可以通過yield關(guān)鍵字產(chǎn)生。
生成器的作用:
減少內(nèi)存占用
比如:利用迭代器的使用方式打開文件
with open("/path/to/file") as f: for line in f: # 這個(gè)地方迭代文件 print(line)
提高運(yùn)行效率
延遲運(yùn)行,僅當(dāng)需要運(yùn)行的地方才開始執(zhí)行
如下例子:
def fibonacci_generator(): a, b = 0, 1 while True: yield a a, b = b, a + b # Print all the numbers of the Fibonacci sequence that are lower than 1000 for i in fibonacci_generator(): if i > 1000: break print(i)
輸出結(jié)果
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
在python中可以使用生成器表達(dá)式去迭代一個(gè)對(duì)象,生成器表達(dá)式和列表最大的差別就在于是否一次性將結(jié)果計(jì)算完成,舉例如下:
a = (x * x for x in range(100)) # a is a generator object print(type(a)) # Sum all the numbers of the generator print(sum(a)) # There are no elements left in the generator print(sum(a))
輸出結(jié)果如下:
collections包常見用法328350 0
collections包是標(biāo)準(zhǔn)庫(kù)的一個(gè)模塊,主要目的是用來擴(kuò)展容器相關(guān)的數(shù)據(jù)類型,
我們通過dir查看collections包有哪些模塊:
>>> import collections >>> dir(collections) ["Callable", "Container", "Counter", "Hashable", "ItemsView", "Iterable", "Iterator", "KeysView", "Mapping", "MappingView", "MutableMapping", "MutableSequence", "MutableSet", "OrderedDict", "Sequence", "Set", "Sized", "ValuesView", "__all__", "__builtins__", "__doc__", "__file__", "__name__", "__package__", "_abcoll", "_chain", "_class_template", "_eq", "_field_template", "_get_ident", "_heapq", "_imap", "_iskeyword", "_itemgetter", "_repeat", "_repr_template", "_starmap", "_sys", "defaultdict", "deque", "namedtuple"]
我們以Counter為例:
from collections import Counter a = Counter("blue") b = Counter("yellow") print(a) print(b) print((a + b).most_common(3))
輸出結(jié)果如下:
Counter({"u": 1, "e": 1, "l": 1, "b": 1}) Counter({"l": 2, "y": 1, "e": 1, "o": 1, "w": 1}) [("l", 3), ("e", 2), ("y", 1)]
另外defaultdict也是我常用的一個(gè)模塊,defaultdict是dict的子類,允許我們通過工廠方法來動(dòng)態(tài)創(chuàng)建不存在的屬性,舉例如下:
from collections import defaultdict my_dict = defaultdict(lambda: "Default Value") my_dict["a"] = 42 print(my_dict["a"]) print(my_dict["b"])
運(yùn)行結(jié)果如下:
42 Default Value
在工作中我經(jīng)常用defaultdict來構(gòu)造一顆樹形數(shù)據(jù)結(jié)構(gòu)來滿足我的常規(guī)需求,實(shí)例如下:
from collections import defaultdict import json def tree(): """ Factory that creates a defaultdict that also uses this factory """ return defaultdict(tree) root = tree() root["Page"]["Python"]["defaultdict"]["Title"] = "Using defaultdict" root["Page"]["Python"]["defaultdict"]["Subtitle"] = "Create a tree" root["Page"]["Java"] = None print(json.dumps(root, indent=4))
運(yùn)行結(jié)果如下:
{ "Page": { "Python": { "defaultdict": { "Subtitle": "Create a tree", "Title": "Using defaultdict" } }, "Java": null } }itertools包常見用法
itertools包也是標(biāo)準(zhǔn)庫(kù)的一個(gè)模塊,他常見的用法是用來擴(kuò)展迭代器的使用,高效的執(zhí)行迭代
我們通過dir方法來查看itertools都有哪些模塊
>>> import itertools >>> dir(itertools) ["__doc__", "__file__", "__name__", "__package__", "chain", "combinations", "combinations_with_replacement", "compress", "count", "cycle", "dropwhile", "groupby", "ifilter", "ifilterfalse", "imap", "islice", "izip", "izip_longest", "permutations", "product", "repeat", "starmap", "takewhile", "tee"]
我們以permutations舉例如下:
from itertools import permutations for p in permutations([1,2,3]): print(p)
輸出結(jié)果:
(1, 2, 3) (1, 3, 2) (2, 1, 3) (2, 3, 1) (3, 1, 2) (3, 2, 1)
combinations示例如下:
from itertools import combinations for c in combinations([1, 2, 3, 4], 2): print(c)
輸出結(jié)果:
(1, 2) (1, 3) (1, 4) (2, 3) (2, 4) (3, 4)
另外chain模塊也是常用模塊之一
chain使用示例:
from itertools import chain for c in chain(range(3), range(12, 15)): print(c)
輸出結(jié)果如下:
0 1 2 12 13 14
另外itertools工具包里還有很多常見的用法,這里不再一一舉例,大家可以自行嘗試。
packing/unpacking特性在函數(shù)參數(shù)里使用*args,**kwargs都很常見,但是以下的幾種用法你們有試過嗎?
a, *b, c = [2, 7, 5, 6, 3, 4, 1] print(a) print(b) print(c)
以上代碼輸出:
2 [7, 5, 6, 3, 4] 1
有同學(xué)抱怨說這樣運(yùn)行不對(duì),會(huì)報(bào)錯(cuò),呵呵,那是因?yàn)槟阌玫膒ython2,python3中已經(jīng)對(duì)pack,unpack特性進(jìn)行了很好的實(shí)現(xiàn)。
剛才我已經(jīng)看到了pack的舉例,我們接下來再看看unpack
def repeat(count, name): for i in range(count): print(name) print("Call function repeat using a list of arguments:") args = [4, "cats"] repeat(*args) print("Call function repeat using a dictionary of keyword arguments:") args2 = {"count": 4, "name": "cats"} repeat(**args2)
運(yùn)行結(jié)果如下:
Call function repeat using a list of arguments: cats cats cats cats Call function repeat using a dictionary of keyword arguments: cats cats cats cats
最后我們?cè)倩貧w到函數(shù)參數(shù)的例子上:
def f(*args, **kwargs): print("Arguments: ", args) print("Keyword arguments: ", kwargs) f(3, 4, 9, foo=42, bar=7)
以上代碼輸出:
Arguments: (3, 4, 9) Keyword arguments: {"bar": 7, "foo": 42}Decorators裝飾器
裝飾器這個(gè)語法糖相信使用flask或者bottle的同學(xué)應(yīng)該都不陌生,使用django的也應(yīng)該經(jīng)常會(huì)遇到,但是大家有沒有去想過這個(gè)語法糖的應(yīng)用場(chǎng)景呢?我簡(jiǎn)單整理了下,大概有以下幾種裝飾器:
緩存裝飾器
權(quán)限驗(yàn)證裝飾器
計(jì)時(shí)裝飾器
日志裝飾器
路由裝飾器
異常處理裝飾器
錯(cuò)誤重試裝飾器
我們拿緩存裝飾器舉例:
def cache(function): cached_values = {} # Contains already computed values def wrapping_function(*args): if args not in cached_values: # Call the function only if we haven"t already done it for those parameters cached_values[args] = function(*args) return cached_values[args] return wrapping_function @cache def fibonacci(n): print("calling fibonacci(%d)" % n) if n < 2: return n return fibonacci(n-1) + fibonacci(n-2) print([fibonacci(n) for n in range(1, 9)])
以上代碼輸出:
calling fibonacci(1) calling fibonacci(2) calling fibonacci(0) calling fibonacci(3) calling fibonacci(4) calling fibonacci(5) calling fibonacci(6) calling fibonacci(7) calling fibonacci(8) [1, 1, 2, 3, 5, 8, 13, 21]
在python3中有一個(gè)包叫做lrucache,就是用的裝飾器的語法糖進(jìn)行實(shí)現(xiàn)。
lrucache的簡(jiǎn)單實(shí)用如下:
from functools import lru_cache @lru_cache(maxsize=None) def fibonacci(n): print("calling fibonacci(%d)" % n) if n < 2: return n return fibonacci(n-1) + fibonacci(n-2) print([fibonacci(n) for n in range(1, 9)])
運(yùn)行結(jié)果:
calling fibonacci(1) calling fibonacci(2) calling fibonacci(0) calling fibonacci(3) calling fibonacci(4) calling fibonacci(5) calling fibonacci(6) calling fibonacci(7) calling fibonacci(8) [1, 1, 2, 3, 5, 8, 13, 21]Context Managers上下文管理期
最后我們?cè)倏磒ython中的上下文管理器,這個(gè)語法糖在資源管理上有很常見的使用場(chǎng)景,比如上文中我用with open("file") as的用法,使用了with后就不用擔(dān)心文件不會(huì)關(guān)閉了,在處理socket編程的時(shí)候也可以用。這個(gè)語法糖其實(shí)也不難就是兩個(gè)魔術(shù)方法的實(shí)現(xiàn),__enter__ 和 __exit__,一個(gè)控制入口,一個(gè)控制出口。
常規(guī)的使用with來統(tǒng)計(jì)一段代碼運(yùn)行時(shí)間的例子:
from time import time class Timer(): def __init__(self, message): self.message = message def __enter__(self): self.start = time() return None # could return anything, to be used like this: with Timer("Message") as value: def __exit__(self, type, value, traceback): elapsed_time = (time() - self.start) * 1000 print(self.message.format(elapsed_time)) with Timer("Elapsed time to compute some prime numbers: {}ms"): primes = [] for x in range(2, 500): if not any(x % p == 0 for p in primes): primes.append(x) print("Primes: {}".format(primes))
輸出結(jié)果:
Primes: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499] Elapsed time to compute some prime numbers: 1.055002212524414ms總結(jié)
其實(shí)python是一門特別人性化的語言,但凡在工程中經(jīng)常遇到的問題,處理起來比較棘手的模式基本都有對(duì)應(yīng)的比較優(yōu)雅的解決方案。有些寫Java同學(xué)寫python代碼經(jīng)常看起來像是寫C,沒有一點(diǎn)python語言的影子,因此簡(jiǎn)單整理了下python進(jìn)階的一些用法,希望能夠幫助一些同學(xué)。
PS:大家如果轉(zhuǎn)載請(qǐng)保留出處和作者
PS:如果希望收到本人更多的技術(shù)筆記歡迎關(guān)注本公共號(hào)或者搜索CodingFutuer進(jìn)行關(guān)注
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/40635.html
摘要:所以如果像上述這樣引入模塊的時(shí)候,調(diào)用函數(shù)必須加上模塊名通常情況下鼓勵(lì)每個(gè)語句只導(dǎo)入一個(gè)包方便理解和閱讀代碼。 今天我們學(xué)習(xí)Python的高級(jí)特性、模塊和IO操作,通過學(xué)習(xí)這些,我們可以更快的了解Python,使用Python。 高級(jí)特性中會(huì)講述列表生成式、生成器、和一些高級(jí)函數(shù),學(xué)習(xí)這些方便我們快速的生成列表,節(jié)省我們使用Python的時(shí)間,更快的使用Python達(dá)成我們的目的。 模...
摘要:開始本文主要記錄廖大教程中高級(jí)特性這一節(jié)的內(nèi)容,并寫下我的一些理解。廖大的教程中是這樣說的函數(shù)是順序執(zhí)行,遇到語句或者最后一行函數(shù)語句就返回。 前言 用 python 差不多半年多了,從去年暑假開始接觸,從開始的懵逼,到寫了一些小爬蟲總算入門之后,許多作業(yè)也是能用 python 就用 python,基本拋棄了 C++。但是還是有些過于急躁了,能夠?qū)懸恍┖?jiǎn)短的代碼,但是對(duì)于 python...
迭代 可以通過 for 循環(huán)來遍歷 list 或 tuple,這種遍歷我們稱為迭代(Iteration)只要是可迭代對(duì)象,都可以迭代,比如字典默認(rèn)情況下,字典迭代的是key值如何讓判斷一個(gè)類型是否可迭代 from collections import Iterable #導(dǎo)入collections模塊的Iterable類型判斷方法 print(isinstance({abc:1},Itera...
摘要:昨天在類的多重繼承那里糾結(jié)了好久在提問版塊提了個(gè)問題探討了探討鏈接才完全搞明白現(xiàn)在把類的特性整理下供以后參考正文首先得說明的是的類分為經(jīng)典類和新式類經(jīng)典類是之前的東西但是在還在兼容但是在之后的版本就只承認(rèn)新式類了新式類在之后的版本中都可以使 昨天在Python類的多重繼承那里糾結(jié)了好久,在提問版塊提了個(gè)問題探討了探討(鏈接)才完全搞明白,現(xiàn)在把類的特性整理下,供以后參考 正文 首先...
閱讀 5759·2021-11-24 10:25
閱讀 2698·2021-11-16 11:44
閱讀 3855·2021-10-11 11:09
閱讀 3176·2021-09-02 15:41
閱讀 3260·2019-08-30 14:14
閱讀 2285·2019-08-29 14:10
閱讀 2348·2019-08-29 11:03
閱讀 1129·2019-08-26 13:47