閉包

Python 函式寫作

Shayne Miel

Software Architect @ Duo Security

將非區域變數附加到巢狀函式

def foo():
  a = 5
  def bar():
    print(a)
  return bar

func = foo()

func()
5

Closures!

type(func.__closure__)
<class 'tuple'>
len(func.__closure__)
1
func.__closure__[0].cell_contents
5
Python 函式寫作

閉包與刪除

x = 25

def foo(value):
  def bar():
    print(value)
  return bar

my_func = foo(x)
my_func()
25
del(x)
my_func()
25
len(my_func.__closure__)
1
my_func.__closure__[0].cell_contents
25
Python 函式寫作

閉包與覆寫

x = 25

def foo(value):
  def bar():
    print(value)
  return bar

x = foo(x)
x()
25
len(x.__closure__)
1
x.__closure__[0].cell_contents
25
Python 函式寫作

定義——巢狀函式

巢狀函式:定義在另一個函式內的函式。

# outer function
def parent():
  # nested function
  def child():
    pass
  return child
Python 函式寫作

定義——非區域變數

非區域變數(nonlocal):在父函式中定義,供子函式使用的變數。

def parent(arg_1, arg_2):
  # 從 child() 的角度看,
  # `value` 和 `my_dict` 是非區域變數,
  # `arg_1` 與 `arg_2` 也是。
  value = 22
  my_dict = {'chocolate': 'yummy'}

  def child():
    print(2 * value)
    print(my_dict['chocolate'])
    print(arg_1 + arg_2)

  return child
Python 函式寫作

閉包(closure):附加在被回傳函式上的非區域變數。

def parent(arg_1, arg_2):
  value = 22
  my_dict = {'chocolate': 'yummy'}

  def child():
    print(2 * value)
    print(my_dict['chocolate'])
    print(arg_1 + arg_2)

  return child

new_function = parent(3, 4)

print([cell.cell_contents for cell in new_function.__closure__])
[3, 4, 22, {'chocolate': 'yummy'}]
Python 函式寫作

為什麼這很重要?

裝飾器會用到:

  • 函式作為物件
  • 巢狀函式
  • 非區域作用域
  • 閉包
Python 函式寫作

一起來練習吧!

Python 函式寫作

Preparing Video For Download...