Hi 大家好,
今天要開始介紹基礎語法中的函數進階篇之續集,那我們開始吧!
Q: 什麼是自由變數?
A: 指的是外層函數內定義的變數,被內層函數引用時,這些變數對內層函數來說就是「自由變數」
def hi():
message = "1111111" <==== 自由變數
def hey():
print(message)
return hey
greeting = hi()
greeting()
Q: 什麼是閉包?
A: 簡單來說就是整包帶著走。
閉包是程式語言的一種特性,指的是在一個函數內定義了另外一個函數,而內層函數能夠引用外層函數的變數,並且記住這個變數,即使外層函數執行完畢並退出。內層函數連同引用到的變數,會形成一個閉包。
以下範例說明:
inner_function
想要印出變數message,但是內層函數並沒有定義,所以會往外面找,如果找到後就會記住這個變數inner_function
函數,但這裡還沒有啟動執行outer_function()
函數回傳inner_function
函數,賦值給greeting
變數greeting
函數加上了()
所以表示會啟動執行函數,等同於會執行inner_function()
,最後印出messagedef outer_function():
message = "Hello World!" <==== 自由變數
def inner_function():
print(message) <==== (1)
return inner_function <==== (2)
greeting = outer_function() <==== (3)
greeting() <==== (4)
PS D:\Project\practice> python hi.py
Hello World!
PS D:\Project\practice>
Q: 什麼是高階函數?
A: 指的是函數可以接收一個到多個函數作為參數,或者可以返回一個函數作為結果的函數。因為函數在Python中被視為一等公民,所以可以把函數當作參數來傳遞。
Q: 什麼是函數裝飾器?
A: 就是利用高階函數可以接收函數和回傳函數的概念和特性,針對接收到的函數增加一些額外的修飾和功能,然後回傳一個新的函數。
[舉個例子]
未使用裝飾器時:
這裡定義了兩個函數deprecated
和hello
,如果hello函數在不久的將來要被拋棄使用,那我想要在不改變原有hello函數的情況下,另外加上註解,以下的方式只會是過水的情況。
def deprecated(fn):
return fn
def hello():
print("Hello World")
hello = deprecated(hello)
hello()
加上裝飾器@deprecated的寫法:
以下方式就是在deprecated函數接收到的hello函數參數,再包一層wrapper函數來針對接收到的hello函數進行修飾,而其中裝飾器@deprecated
會等同於hello = deprecated(hello)
的寫法。
def deprecated(fn):
def wrapper():
# 調用原始hello函數做一些事情
print(f"Warning: \"{fn.__name__}()\" is deprecated and will be removed")
return fn()
return wrapper
@deprecated
def hello():
print("Hello World")
hello()
PS D:\Project\practice> python hi.py
Warning: "hello()" is deprecated and will be removed <==== 新增加的修飾
Hello World <==== 原本函數的內容沒有被改變
PS D:\Project\practice>
Q: 什麼是語法糖?
A: 這是設計者提供的一種語法,讓原本看起來很複雜的邏輯,在套用語法糖後,會使得程式碼更簡潔、更容易閱讀。函數裝飾器語法(使用@
符號)就是一種語法糖。
那今天就介紹到這裡,我們明天見~