2016年9月6日 星期二

[ Python 常見問題 ] Python Closures and the Python 2.7 nonlocal Solution

Source From Here 
Preface 
In python, functions are first class. A language with first class functions allows functions to be passed as a variable and returned from a function just like other first class data types like integers or floats. Some notable language with first class functions are Python, JavaScript, Scheme and Haskell. Therefore in python, it’s possible to do things like this: 
  1. def raise_to_base(n):  
  2.   def my_pow(x):  
  3.     return x**n  
  4.   return my_pow  
>>> pow_base5 = raise_to_base(5)
>>> pow_base5(2) # 2^5 = 32
32

I have created a function that returns another function. And the inner function is known as a closureA “closure” is an expression (typically a functionthat can have free variables together with an environment that binds those variables (that “closes” the expression). With closures, we can do other neat things like this: 
  1. def outer():  
  2.   y = 0  
  3.   def inner():  
  4.     nonlocal y  
  5.     y+=1  
  6.     return y  
  7.   return inner  
>>> f = outer()

>>> f()
1
>>> f()
2
>>> f()
3

The inner function now becomes something like a method in OOP. It controls the way the variable y is accessed from the outside. 

Problem and HowTo 
But there’s a problem when we want to do this in Python 2.7. The above code works only in Python 3.x. The nonlocal keyword does not exist in Python 2.7. To solve this problem, we can use dictionaries (or we can also create another object) to store the y variable in a namespace that the inner function can access. 
  1. def outer():  
  2.   d = {'y' : 0}  
  3.   def inner():  
  4.     d['y'] += 1  
  5.     return d['y']  
  6.   return inner  
>>> f = outer()
>>> f()
1
>>> f()
2
>>> f1 = outer()
>>> f1()
1

Supplement 
[Python 學習筆記] 函式、類別與模組 : 函式 (lambda 運算式)

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...