久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Python進(jìn)階系列(一)

 zhulin1028 2022-06-16 發(fā)布于山東

使用 *args 和 **kwargs 來調(diào)用函數(shù)

那現(xiàn)在我們將看到怎樣使用*args和**kwargs 來調(diào)用一個(gè)函數(shù),。 假設(shè),你有這樣一個(gè)小函數(shù):

def test_args_kwargs(arg1, arg2, arg3):

??? print("arg1:", arg1)

??? print("arg2:", arg2)

??? print("arg3:", arg3)

你可以使用*args或**kwargs來給這個(gè)小函數(shù)傳遞參數(shù),。 下面是怎樣做:

# 首先使用 *args

args = ("two", 3, 5)

test_args_kwargs(*args)

arg1: two

arg2: 3

arg3: 5

# 現(xiàn)在使用 **kwargs:

kwargs = {"arg3": 3, "arg2": "two", "arg1": 5}

test_args_kwargs(**kwargs)

arg1: 5

arg2: two

arg3: 3

標(biāo)準(zhǔn)參數(shù)與*args,、**kwargs在使用時(shí)的順序

那么如果你想在函數(shù)里同時(shí)使用所有這三種參數(shù), 順序是這樣的:

some_func(fargs, *args, **kwargs)

什么時(shí)候使用它們?

這還真的要看你的需求而定。

最常見的用例是在寫函數(shù)裝飾器的時(shí)候(會(huì)在另一章里討論),。

此外它也可以用來做猴子補(bǔ)丁(monkey patching),。猴子補(bǔ)丁的意思是在程序運(yùn)行時(shí)(runtime)修改某些代碼。

打個(gè)比方,你有一個(gè)類,里面有個(gè)叫g(shù)et_info的函數(shù)會(huì)調(diào)用一個(gè)API并返回相應(yīng)的數(shù)據(jù),。如果我們想測試它,可以把API調(diào)用替換成一些測試數(shù)據(jù),。例

如:

import someclass

def get_info(self, *args):

??? return "Test data"

someclass.get_info = get_info

我敢肯定你也可以想象到一些其他的用例。

生成器(Generators)

首先我們要理解迭代器(iterators),。根據(jù)維基百科,迭代器是一個(gè)讓程序員可以遍歷一個(gè)容器(特別是列表)的對(duì)象,。然而,一個(gè)迭代器在遍歷并讀取一個(gè)容器的數(shù)據(jù)元素時(shí),并不會(huì)執(zhí)行一個(gè)迭代。你可能有點(diǎn)暈了,那我們來個(gè)慢動(dòng)作,。換句話說這里有三個(gè)部分:

可迭代對(duì)象(Iterable)

迭代器(Iterator)

迭代(Iteration)

上面這些部分互相聯(lián)系,。我們會(huì)先各個(gè)擊破來討論他們,然后再討論生成器(generators).

可迭代對(duì)象(Iterable)

Python中任意的對(duì)象,只要它定義了可以返回一個(gè)迭代器的__iter__方法,或者定義了可以支持下標(biāo)索引的__getitem__方法(這些雙下劃線方法會(huì)在其他章節(jié)中全面解釋),那么它就是一個(gè)可迭代對(duì)象。簡單說,可迭代對(duì)象就是能提供迭代器的任意對(duì)象,。那迭代器又是什么呢?

迭代器(Iterator)

任意對(duì)象,只要定義了next(Python2) 或者_(dá)_next__方法,它就是一個(gè)迭代器,。就這么簡單。現(xiàn)在我們來理解迭代(iteration)

迭代(Iteration)

用簡單的話講,它就是從某個(gè)地方如一個(gè)列表)取出一個(gè)元素的過程,。當(dāng)我們使用一個(gè)循環(huán)來遍歷某個(gè)東西時(shí),這個(gè)過程本身就叫迭代?,F(xiàn)在既然我們有了這些術(shù)語的基本理解,那我們開始理解生成器吧。

生成器(Generators)

生成器也是一種迭代器,但是你只能對(duì)其迭代一次,。這是因?yàn)樗鼈儾]有把所有的值存在內(nèi)存中,而是在運(yùn)行時(shí)生成值,。你通過遍歷來使用它們,要么用一個(gè)“for”循環(huán),要么將它們傳遞給任意可以進(jìn)行迭代的函數(shù)和結(jié)構(gòu)。大多數(shù)時(shí)候生成器是以函數(shù)來實(shí)現(xiàn)的,。然而,它們并不返回一個(gè)值,而是yield(暫且譯作“生出”)一個(gè)值,。這里有個(gè)生成器函數(shù)的簡單例子:

def generator_function():

??? for i in range(10):

??????? yield i


for item in generator_function():

??? print(item)

這個(gè)案例并不是非常實(shí)用。生成器最佳應(yīng)用場景是:你不想同一時(shí)間將所有計(jì)算出來的大量結(jié)果集分配到內(nèi)存當(dāng)中,特別是結(jié)果集里還包含循環(huán),。

譯者注:這樣做會(huì)消耗大量資源

許多Python 2里的標(biāo)準(zhǔn)庫函數(shù)都會(huì)返回列表,而Python 3都修改成了返回生成器,因?yàn)樯善髡加酶俚馁Y源。

下面是一個(gè)計(jì)算斐波那契數(shù)列的生成器:

# generator version

def fibon(n):

??? a = b = 1

??? for i in range(n):

??????? yield a

??????? a, b = b, a + b


# Now we can use it like this

for x in fibon(1000000):

??? print(x)

用這種方式,我們可以不用擔(dān)心它會(huì)使用大量資源,。然而,之前如果我們這樣來實(shí)現(xiàn)的話:

def fibon(n):

??? a = b = 1

??? result = []

??? for i in range(n):

??????? result.append(a)

??????? a, b = b, a + b

??? return result

這也許會(huì)在計(jì)算很大的輸入?yún)?shù)時(shí),用盡所有的資源,。我們已經(jīng)討論過生成器使用一次迭代,但我們并沒有測試過。在測試前你需要再知道一個(gè)Python內(nèi)置函數(shù):next(),。它允許我們獲取一個(gè)序列的下一個(gè)元素,。那我們來驗(yàn)證下我們的理解:

def generator_function():

??? for i in range(3):

??????? yield i

gen = generator_function()

print(next(gen))

# Output: 0

print(next(gen))

# Output: 1

print(next(gen))

# Output: 2

print(next(gen))

# Output: Traceback (most recent call last):

#?????????? File "<stdin>", line 1, in <module>

#?????????? StopIteration

我們可以看到,在yield掉所有的值后,next()觸發(fā)了一個(gè)StopIteration的異常?;旧线@個(gè)異常告訴我們,所有的值都已經(jīng)被yield完了,。你也許會(huì)奇怪,為什么我們?cè)谑褂胒or循環(huán)時(shí)沒有這個(gè)異常呢?啊哈,答案很簡單。for循環(huán)會(huì)自動(dòng)捕捉到這個(gè)異常并停止調(diào)用next(),。你知不知道Python中一些內(nèi)置數(shù)據(jù)類型也支持迭代哦?我們這就去看看:

my_string = "Yasoob"

next(my_string)

# Output: Traceback (most recent call last):

#?????? File "<stdin>", line 1, in <module>

#?????? TypeError: str object is not an iterator

好吧,這不是我們預(yù)期的,。這個(gè)異常說那個(gè)str對(duì)象不是一個(gè)迭代器,。對(duì),就是這樣!它是一個(gè)可迭代對(duì)象,而不是一個(gè)迭代器。這意味著它支持迭代,但我們不能直接對(duì)其進(jìn)行迭代操作,。那我們?cè)鯓硬拍軐?duì)它實(shí)施迭代呢?是時(shí)候?qū)W習(xí)下另一個(gè)內(nèi)置函數(shù),iter,。它將根據(jù)一個(gè)可迭代對(duì)象返回一個(gè)迭代器對(duì)象。這里是我們?nèi)绾问褂盟?#xff1a;

my_string = "Yasoob"

my_iter = iter(my_string)

next(my_iter)

# Output: 'Y'

現(xiàn)在好多啦,。我肯定你已經(jīng)愛上了學(xué)習(xí)生成器,。一定要記住,想要完全掌握這個(gè)概念,你只有使用它。確保你按照這個(gè)模式,并在生成器對(duì)你有意義的任何時(shí)候都使用它,。你絕對(duì)不會(huì)失望的!

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多