面向?qū)ο笏枷氲膶崿F(xiàn)
class Averager(): def __init__(self): self.series = [] def __call__(self, new_value): self.series.append(new_value) total = sum(self.series) return total/len(self.series)
>>> avg(10) 10.0 >>> avg(11) 10.5 >>> avg(12) 11.0函數(shù)式編程思想的實現(xiàn)
def make_averager(): series = [] def averager(new_value): series.append(new_value) total = sum(series) return total/len(series) return averager
>>> avg = make_averager() >>> avg(10) 10.0 >>> avg(11) 10.5 >>> avg(12) 11.0
nonlocal關(guān)鍵字
def make_averager(): count = 0 total = 0 def averager(new_value): count += 1 total += new_value return total / count return averager
>>> avg = make_averager() >>> avg(10) Traceback (most recent call last): ... UnboundLocalError: local variable "count" referenced before assignment >>>
The problem is that the statement count += 1 actually means the same as count = count + 1, when count is a number or any immutable type. So we are actually assigning to count in the body of averager, and that makes it a local variable. The same problem affects the total variable.
We did not have this problem in the example because we never assigned to the series list, we only called series.append and invoked sum and len on it. So we took advantage of the fact that lists are mutable. But with immutable types like numbers, strings, tuples etc., all you can is read, but never update. If you try to rebind them, as in count = count + 1, then you are implicitly creating a local variable count. It is no longer a free variable, therefore it is not saved in the closure.
To work around this the nonlocal declaration was introduced in Python 3. It lets you flag a variable as a free variable even when it is assigned a new value within the function. If a new value is assigned to a nonlocal variable, the binding stored in the closure is changed.
def make_averager(): count = 0 total = 0 def averager(new_value): nonlocal count, total count += 1 total += new_value return total / count return averager帶參數(shù)的裝飾器
def use_logging(level): def decorator(func): def wrapper(*args, **kwargs): if level == "warn": logging.warn("%s is running" % func.__name__) elif level == "info": logging.info("%s is running" % func.__name__) return func(*args) return wrapper return decorator @use_logging(level="warn") def foo(name="foo"): print("i am %s" % name) foo()Stacked decorators
@d1 @d2 def f(): print("f") # equivalent to def f(): print("f") f = d1(d2(f))
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/38388.html
摘要:作者按每天一個設(shè)計模式旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用和兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當?shù)膶崿F(xiàn)方式原文地址是每天一個設(shè)計模式之裝飾者模式歡迎關(guān)注個人技術(shù)博客。 作者按:《每天一個設(shè)計模式》旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用javascript和python兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當?shù)膶崿F(xiàn)方式...
摘要:作者按每天一個設(shè)計模式旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用和兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當?shù)膶崿F(xiàn)方式原文地址是每天一個設(shè)計模式之裝飾者模式歡迎關(guān)注個人技術(shù)博客。 作者按:《每天一個設(shè)計模式》旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用javascript和python兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當?shù)膶崿F(xiàn)方式...
閱讀 1436·2021-09-22 16:04
閱讀 2800·2019-08-30 15:44
閱讀 888·2019-08-30 15:43
閱讀 767·2019-08-29 15:24
閱讀 1845·2019-08-29 14:07
閱讀 1135·2019-08-29 12:30
閱讀 1730·2019-08-29 11:15
閱讀 2741·2019-08-28 18:08