__call__ 方法是python的魔術(shù)方法,就是增加一些特殊功能,我們來看看 __call__ 代表了什么意思?
三門峽網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)從2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
python中所有的東西都被稱為對(duì)象,對(duì)象分為可以被調(diào)用和不可以被調(diào)用
可調(diào)用對(duì)象:許多Python對(duì)象都是我們所說的可調(diào)用的,即是任何通過函數(shù)操作符 () 來調(diào)用的對(duì)象
1.例如函數(shù)
函數(shù)是對(duì)象,可以被調(diào)用
2.但是如果是類的話會(huì)發(fā)生什么情況呢?
Python給類提供了名為 __call__ 的特別方法,該方法允許程序員創(chuàng)建可調(diào)用的對(duì)象(實(shí)例)。默認(rèn)情況下, __call__ 方法是沒有實(shí)現(xiàn)的,這意味著大多數(shù)情況下實(shí)例是不可調(diào)用的。
如何解決這一個(gè)問題?這里就用到 __call__ 函數(shù)
以上說明 __call__
Iamlaosong文
我們?cè)谟胒or ... in ...語句循環(huán)時(shí),in后面跟隨的對(duì)象要求是可迭代對(duì)象,即可以直接作用于for循環(huán)的對(duì)象統(tǒng)稱為可迭代對(duì)象(Iterable),如list、tuple、dict、set、str等。
可迭代對(duì)象是實(shí)現(xiàn)了__iter__()方法的對(duì)象,而迭代器(Iterator)則是實(shí)現(xiàn)了__iter__()和__next__()方法的對(duì)象,可以顯示地獲取下一個(gè)元素。這種可以被next調(diào)用并不斷返回下一個(gè)值的對(duì)象稱為迭代器。迭代器一定是可迭代對(duì)象,反過來則不一定成立。用iter()函數(shù)可以把list、dict、str等Iterable變成Iterator,例如:
bb=[x for x in range(10)]
cc=iter(bb)
cc.next()
循環(huán)變量的值其實(shí)可以看著是一次次用next取值的過程,每取一個(gè)值,做一次處理。list等對(duì)象用于循環(huán)實(shí)際上可以看著是用iter()方法產(chǎn)生一個(gè)迭代器,然后循環(huán)取值。
生成器(generator)就是一個(gè)能返回迭代器的函數(shù),其實(shí)就是定義一個(gè)迭代算法,可以理解為一個(gè)特殊的迭代器。調(diào)用這個(gè)函數(shù)就得到一個(gè)迭代器,生成器中的yield相當(dāng)于一個(gè)斷點(diǎn),執(zhí)行到此返回一個(gè)值后暫停,從而實(shí)現(xiàn)next取值。
這兩個(gè)方法都能開始線程活動(dòng),但是用法不同,其區(qū)別與Java Thread類中start()和run()的區(qū)別類似。
先來看官方文檔的說明:
翻譯過來就是:
start()方法
開始線程活動(dòng)。
對(duì)每一個(gè)線程對(duì)象來說它只能被調(diào)用一次,它安排對(duì)象在一個(gè)另外的單獨(dú)線程中調(diào)用run()方法(而非當(dāng)前所處線程)。
當(dāng)該方法在同一個(gè)線程對(duì)象中被調(diào)用超過一次時(shí),會(huì)引入RuntimeError(運(yùn)行時(shí)錯(cuò)誤)。
run()方法
代表了線程活動(dòng)的方法。
你可以在子類中重寫此方法。標(biāo)準(zhǔn)run()方法調(diào)用了傳遞給對(duì)象的構(gòu)造函數(shù)的可調(diào)對(duì)象作為目標(biāo)參數(shù),如果有這樣的參數(shù)的話,順序和關(guān)鍵字參數(shù)分別從args和kargs取得。
為了測(cè)試寫了如下代碼:
[python]?view plain?copy
#!/usr/bin/python
#?coding=utf-8
import?threading
class?myThread(threading.Thread):
def?__init__(self,?threadID,?name,?counter):
threading.Thread.__init__(self)
self.threadID?=?threadID
self.name?=?name
self.counter?=?counter
def?run(self):
currentTreadname?=?threading.currentThread()
print?"running?in",?currentTreadname
thread?=?myThread(1,"mythrd",1)
thread.run()
thread.start()
myThread繼承自Thread類,我重寫了它的構(gòu)造函數(shù)和run()方法,run()方法通過currentThread()獲取當(dāng)前所處線程名稱并用print函數(shù)打印
然后程序分別執(zhí)行run()和start()方法
輸出結(jié)果如下:
可以看到兩個(gè)方法分別處于MainThread和myThread線程中
__call__
在Python中,函數(shù)其實(shí)是一個(gè)對(duì)象:
f = abs
f.__name__
'abs'
f(-123)
由于 f 可以被調(diào)用,所以,f 被稱為可調(diào)用對(duì)象。
所有的函數(shù)都是可調(diào)用對(duì)象。
一個(gè)類實(shí)例也可以變成一個(gè)可調(diào)用對(duì)象,只需要實(shí)現(xiàn)一個(gè)特殊方法__call__()。
我們把 Person 類變成一個(gè)可調(diào)用對(duì)象:
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print 'My name is %s...' % self.name
print 'My friend is %s...' % friend
現(xiàn)在可以對(duì) Person 實(shí)例直接調(diào)用:
p = Person('Bob', 'male')
p('Tim')
My name is Bob...
My friend is Tim...
單看 p('Tim') 你無法確定 p 是一個(gè)函數(shù)還是一個(gè)類實(shí)例,所以,在Python中,函數(shù)也是對(duì)象,對(duì)象和函數(shù)的區(qū)別并不顯著。
任務(wù)
改進(jìn)一下前面定義的斐波那契數(shù)列:
class Fib(object):
???
請(qǐng)加一個(gè)__call__方法,讓調(diào)用更簡單:
f = Fib()
print f(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
python函數(shù)傳對(duì)象對(duì)性能有影響。在Python中,一切皆對(duì)象,Python參數(shù)傳遞采用的都是“傳對(duì)象引用”的方式。實(shí)際上,這種方式相當(dāng)于傳值和傳引用的一種綜合。如果函數(shù)收到的是一個(gè)可變對(duì)象(比如字典或者列表)的引用,就能修改對(duì)象的原始值,相當(dāng)于通過“傳引用”來傳遞對(duì)象。如果函數(shù)收到的是一個(gè)不可變對(duì)象(比如數(shù)字、字符或者元組)的引用,就不能直接修改原始對(duì)象,相當(dāng)于通過“傳值’來傳遞對(duì)象,此時(shí)如果想改變這些變量的值,可以將這些變量申明為全局變量。
新聞名稱:python可調(diào)對(duì)象函數(shù),python中可變對(duì)象
標(biāo)題來源:http://vcdvsql.cn/article28/hsedcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、建站公司、服務(wù)器托管、手機(jī)網(wǎng)站建設(shè)、品牌網(wǎng)站建設(shè)、全網(wǎng)營銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)