3 回答

TA貢獻(xiàn)2019條經(jīng)驗(yàn) 獲得超9個(gè)贊
擴(kuò)大伊格納西奧的答案:
def counter():
count = 0
def c():
nonlocal count
count += 1
return count
return c
x = counter()
print([x(),x(),x()])
在Python 3中給出[1,2,3];counter()給獨(dú)立計(jì)數(shù)器的調(diào)用。其他解決方案-尤其是使用itertools/ yield更慣用。

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超4個(gè)贊
您可以這樣做,它或多或少會(huì)以相同的方式工作:
class counter(object):
def __init__(self, count=0):
self.count = count
def __call__(self):
self.count += 1
return self.count
或者,有點(diǎn)hack:
def counter():
count = [0]
def incr(n):
n[0] += 1
return n[0]
return lambda: incr(count)
我會(huì)選擇第一個(gè)解決方案。
編輯:這就是我不閱讀文本大博客所得到的。
無論如何,Python閉包相當(dāng)有限的原因是“因?yàn)镚uido感到喜歡”。Python是在90年代初期(即OO鼎盛時(shí)期)設(shè)計(jì)的。在人們想要的語言功能列表中,閉包率相當(dāng)?shù)?。隨著諸如一流函數(shù),閉包之類的功能思想逐漸成為主流,諸如Python之類的語言不得不加以堅(jiān)持,因此它們的使用可能有點(diǎn)尷尬,因?yàn)檫@不是該語言的設(shè)計(jì)目的。
<rant on="Python scoping">
另外,Python(2.x)在范圍界定方面有很多奇怪的想法(在我看來),它們影響了閉包的合理實(shí)現(xiàn)等。它總是讓我感到困擾:
new = [x for x in old]
x在我們使用的范圍內(nèi)給我們定義名稱,因?yàn)樗ㄔ谖铱磥恚┦歉拍钌陷^小的范圍。(盡管Python獲得了一致性點(diǎn),因?yàn)槭褂胒or循環(huán)執(zhí)行相同的操作具有相同的行為。避免這種情況的唯一方法是使用map。)
無論如何, </rant>

TA貢獻(xiàn)1842條經(jīng)驗(yàn) 獲得超21個(gè)贊
我會(huì)使用發(fā)電機(jī):
>>> def counter():
count = 0
while True:
count += 1
yield(count)
>>> c = counter()
>>> c.next()
1
>>> c.next()
2
>>> c.next()
3
編輯:我相信您的問題的最終答案是PEP-3104:
在大多數(shù)支持嵌套作用域的語言中,代碼可以引用或重新綁定(分配給)最近的封閉作用域中的任何名稱。當(dāng)前,Python代碼可以在任何封閉范圍內(nèi)引用名稱,但只能在兩個(gè)范圍內(nèi)重新綁定名稱:本地范圍(通過簡(jiǎn)單分配)或模塊全局范圍(使用全局聲明)。
在Python-Dev郵件列表和其他地方已經(jīng)多次提出了此限制,并且導(dǎo)致了擴(kuò)展討論和許多關(guān)于消除此限制的方法的建議。該P(yáng)EP總結(jié)了已提出的各種備選方案,以及每種方案的優(yōu)缺點(diǎn)。
在2.1版之前,Python對(duì)范圍的處理類似于標(biāo)準(zhǔn)C的處理:在文件中,只有兩個(gè)級(jí)別的范圍:全局和局部。在C語言中,這是自然的結(jié)果,因?yàn)楹瘮?shù)定義不能嵌套。但是在Python中,盡管函數(shù)通常是在頂層定義的,但是函數(shù)定義可以在任何地方執(zhí)行。這使Python看起來沒有嵌套語義的嵌套作用域的語法外觀,并產(chǎn)生了一些程序員驚訝的不一致之處-例如,在頂層使用的遞歸函數(shù)在移入另一個(gè)函數(shù)時(shí)將停止工作,因?yàn)檫f歸函數(shù)的自己的名字在其范圍內(nèi)將不再可見。
添加回答
舉報(bào)