from dis import dis b = 6 def f1(a): print(a)print(b) b = 9 f1(3) print(dis(f1)) # dis模塊能夠查看python函數字節碼
解決報錯的方案一:申明b全局變量python
from dis import dis b = 6 def f1(a): print(a) global b print(b) b = 9 f1(3) print(dis(f1)) # dis模塊能夠查看python函數字節碼
計算移動平均值閉包
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 = Averager() print(avg(10)) print(avg(11)) print(avg(12))
經過高階函數實現app
def make_averager(): series = [] def averager(new_value): series.append(new_value) total = sum(series) return total/len(series) return averager avg = make_averager() print(avg(10)) print(avg(11)) print(avg(12)) print(avg.__code__.co_varnames) # 打印局部變量 print(avg.__code__.co_freevars) # 打印自由變量 print(avg.__closure__) # series的綁定在返回的函數的__closure__屬性中 print(avg.__closure__[0].cell_contents) # 這些元素是cell對象,有個cell_contents屬性,保存着真正的值 # 綜上,閉包是一種函數,它會保留定義函數時存在的自由變量的綁定,這樣調用函數時,雖然定義做用域不可用了,可是仍能使用那些綁定 # 注意,只有嵌套在其餘函數中的函數纔可能須要處理不在全局做用域中的外部變量
若是是賦值操做呢?函數
def make_averager(): count = 0 total = 0 def averager(new_value): count += 1 total +=new_value return total / count return averager # 這裏直接執行會報錯,由於count += 1 至關於count = count + 1,所以當在averager的定義體內爲count賦值,會把count變成局部變量。total變量也是同理
解決方案this
# 引入nonlocal聲明,做用是把變量標記爲自由變量 def make_averager(): count = 0 total = 0 def averager(new_value): nonlocal count, total count += 1 total += new_value return total / count return averager
裝飾器代碼一spa
def deco(func): def inner(*args, **kwargs): print('this is inner') return inner @deco def foo(): print('this is foo') foo() # this is inner print(foo.__name__) # inner
裝飾器代碼二code
def wrap(func): def deco(*args, **kwargs): print('deco ==> ', args, kwargs) func(*args, **kwargs) print('this is inner') return deco @wrap def foo(*args, **kwargs): print('this is foo') foo() # deco ==> () {} # this is foo # this is inner print(foo.__name__) # deco
裝飾器代碼三對象
from functools import wraps def wrap(func): @wraps(func) def deco(*args, **kwargs): print('deco ==> ', args, kwargs) func(*args, **kwargs) print('this is inner') return deco @wrap def foo(*args, **kwargs): print('this is foo') foo() # deco ==> () {} # this is foo # this is inner print(foo.__name__) # foo
有空講解0.0blog