Python3 函數
- 函數文字定義:函數是組織好的,可重複使用的,用來實現單一,或相關聯功能的代碼段;函數能提高應用的模塊性,和代碼的重複利用率。
定義函數
函數的定義有以下規則:
- 函數代碼塊以 def 關鍵詞開頭,後接函數標識符名稱和圓括號 ()。
- 任何傳入參數和自變量必須放在圓括號之中,圓括號之中可以用於定義參數。
- 函數內容以冒號起始,並且縮進。
- return [表達式] 結束函數,選擇性地返回一個值給調用方。不帶表達式的return相當於返回 None。
定義語法
def 函數名(參數):
函數體
示例
# 輸出hello world函數
def HelloWorld():
print('Hello world')
# 函數調用
HelloWorld()
幾種參數的用法
1、默認參數
在函數調用時,可以不傳送值的參數;或者說,有默認值的參數
- 默認參數的值可以被覆蓋
- 默認參數必須在參數列表的最後
- 默認參數在函數裏只分配一次
-示例:
# 例1:
#!/usr/bin/python3
import random
def choose_num(s,e=10):
num = random.randint(s,e)
return num
choose_num(3) # 調用時只傳了s,未傳e,e用的默認值
輸出 5
choose_num(1,50) # 默認值被覆蓋
輸出 28
# 示例2,默認值必須在最後
#!/usr/bin/python3
def choose_num(s=10,e): # 默認值放前邊,報錯了。
num = random.randint(s,e)
return num
choose_num(3)
報錯
File "<ipython-input-18-16c067f4bcb8>", line 1
def choose_num(s=10,e):
^
SyntaxError: non-default argument follows default argument
def choose_num(s, e=10, n=5):
numbers = []
for x in range(n):
num = random.randint(s,e)
numbers.append(num)
return numbers
choose_num(3)
輸出
[6, 7, 4, 3, 8]
# 示例3,默認值只分配一次
#!/usr/bin/python3
def f(a,L=[]): # 由於默認值只在內存裏分配一次,所以當此列表做默認值時,
L.append(a) # 結果不管調用多少次,都是往已經分配好的列表中追加的
return L # 就是結果中的樣子。
# 而不是第一次返回 [1] 第二次返回[2] 第三次返回[3]
print(f(1))
print(f(2))
print(f(3))
輸出
[1]
[1, 2]
[1, 2, 3]
2、關鍵參數(k=v 方式給參數傳值)
示例代碼:
#!/usr/bin/python3
def car(color,price='10',user='yhyang'):
print(f'{user}有一輛{color}色的車,價值{price}塊')
car('藍') # 其它的使用默認參數
car('紅','30','hmm') # 對應位置覆蓋
car(color='blue',price='100',) # k=v的方式給參數傳值,
輸出
yhyang有一輛藍色的車,價值10塊
hmm有一輛紅色的車,價值30塊
yhyang有一輛blue色的車,價值100塊
3、任意參數
用 *args , **kwargs
作參數,args->tuple,kwargs->dict
示例代碼:
#!/usr/bin/python3
def car(*args): # 一個*號跟args,即 *args 可以成爲一個元組
print(args) # 兩個*號跟kwargs 即 **kwargs 可以成爲一個字典
for k in args: # 重點在於*號有幾個,不在於args kwargs的名稱
print(k)
car("red",10,"yhyang")
輸出
('red', 10, 'yhyang')
red
10
yhyang
#!/usr/bin/python3
def car(**kw): # 這種參數,在傳遞的時候需要傳遞 key=value的方式,才能按字典的方式存儲並打印
for k,v in kw.items():
print(f'{k}::{v}')
car(color='red',price=20,user='yhyang')
輸出
color::red
price::20
user::yhyang
#!/usr/bin/python3
def car(*args,**kw): # 可以識別單個參數和key value參數
print('args:',args)
print('kw:',kw)
for k in args:
print(k)
for k,v in kw.items():
print(f'{k}::{v}')
car('adfsdf','t',color='red',price=20,user='yhyang') # 可以識別單個參數和key value參數
輸出
args: ('adfsdf', 't')
kw: {'color': 'red', 'price': 20, 'user': 'yhyang'}
adfsdf
t
color::red
price::20
user::yhyang
4、注意:直接傳字典名字的時候要加兩個*號
示例代碼:
#!/usr/bin/python3
kwargs = {'color':'red','price':30,}
def car(**kw):
print(kw)
car(**kwargs) #這裏注意,傳字典名字的時候前面要加兩個*
輸出
{'color': 'red', 'price': 30}
5、下面這種寫法,* 參數可傳可不傳,但是price一定要傳,而且是以key value的方式來傳
示例代碼:
#!/usr/bin/python3
def car(color='blue',*,price):
print(color,price)
car(price=30)
輸出
blue 30
函數註釋與文檔說明(annotations,doc)
示例代碼:
#!/usr/bin/python3
def add(x,y):
"""Add x and y together.""" # 函數文檔說明,寫在函數定義的第一行,就可以用
return x+y # 函數名.__doc__來查看函數說明文檔
add.__doc__
輸出
'Add x and y together.'
- 下邊例子中,x:int y:'這個參數隨便' 是對x 和y的說明 ;-> int 是對函數返回值的說明,在執行過程中,會將這個說明忽略
- doc 來獲取函數說明文檔,annotations來獲取函數參數及返回值
示例代碼:
#!/usr/bin/python3
def add(x:int, y:'這個參數隨便')-> int:
"""Add x and y together."""
return x+y
add.__doc__
add.__annotations__
輸出
'Add x and y together.'
{'x': int, 'y': '這個參數隨便', 'return': int}
函數變量的作用域
變量作用域,在自己屋幹自己的事兒
- 本地(局部)
- 封閉
- 全局
- 內置
示例代碼:
# 以下代碼會報錯
#!/usr/bin/python3
x = 1 # 全局
def add():
x += 1 # 局部變量賦值錯誤,此處x沒有被聲明,所以不能被賦值,此處x不是全局的x
print(x)
add()
error_list = [2,3,5]
def big_list():
error_list += [99] # 此處是error_list = error_list + [99],需要先在函數內部聲明error_list,纔不會報錯
print(error_list)
big_list()
示例代碼:
#!/usr/bin/python3
error_list = [2,3,5]
def big_list():
error_list.append(88) # 此處是在全局變量的基礎上追加,所以可以。
print(error_list)
big_list()
輸出
[2, 3, 5, 88]
error_list = [2,3,5]
def big_list():
error_list = [] # 事先聲明才能做下邊的 += 操作
error_list += [99]
print(error_list)
big_list()
輸出
[99]
函數嵌套
函數是python裏面的一級對象,可以用在任何地方,函數裏的作用域屬於封閉作用域
- 一級對象
- 在運行時創建
- 能賦值給變量或數據結構
- 作爲參數傳遞給函數
- 能作爲函數的返回結果
示例代碼:
# 函數嵌套
#!/usr/bin/python3
def calc(x,y):
def add(x,y):
print('x+y:',x+y)
def sub(x,y):
print('x-y:',x-y)
def mul(x,y):
print('x*y:',x*y)
add(x,y) # 在函數內部直接執行嵌套的函數
sub(x,y)
calc(2,5)
輸出
x+y: 7
x-y: -3
# 返回值爲函數本身
#!/usr/bin/python3
def calc(x,y):
def add(x,y):
print('x+y:',x+y)
def sub(x,y):
print('x-y:',x-y)
def mul(x,y):
print('x*y:',x*y)
add(x,y) # 在函數內部直接執行嵌套的函數
sub(x,y)
return mul # 返回 mul函數本身,可以賦給變量
calc(3,5)
輸出
x+y: 8
x-y: -2
<function __main__.calc.<locals>.mul(x, y)>
c = calc(3,5) # c 被賦值爲mul函數
輸出
x+y: 8
x-y: -2
閉包
函數返回值爲內部函數的名字,內部函數又處理外層函數變量;這個整體叫閉包
示例代碼:
# 閉包
#!/usr/bin//python3
def hello():
s = 'yhyang' # s變量在函數中是自由變量
def say():
print(s)
return say # 返回內部函數名,內部函數綁定了外層函數的變量
hello()
h = hello()
h() # h 得到的值爲say()函數,再次執行,則會用到外層函數的變量s
輸出
<function __main__.hello.<locals>.say()>
yhyang
函數閉包,或者閉包函數,本質是一種函數,可以在函數運行以後,依然存在自由變量(或者說可用變量),可以對閉包的數據進行隱藏,避免使用全局變量
如上邊 hello中的變量 s一樣,在第一次執行h = hello的時候,隱藏了s,此時s爲自由變量,依然存在,可以繼續使用。