目錄
函數的定義
定義函數的關鍵字def。函數名,本例函數名是test。小括號裏面是參數。冒號後縮進的代碼塊是函數內容。函數的註釋用""",使用雙引號是爲了規範。return返回值。pass說明函數結束,其實pass不加也沒問題,但是爲了規範還是寫上吧。
Python解釋器逐行解釋,如果函數test定義一次以後,再定義一個函數test,那麼就test就以最後一次定義的爲準。
def test(x):
"""
function test
:param x: 整數
:return: 返回x的立方值
"""
y = x ** 3
return y
pass
def test():
"""
function test
這就重新定義了函數test
:return: 9527
"""
return 9527
pass
val = test()
print(val)
# 9527
函數的返回值
Python的返回值和Java一樣也是隻有一個返回值。因爲Python有了元組這個容器類型,所以多個返回值可以被轉換爲一個元組返回。看起來可以返回多個值,而且實際上你也可以這麼用。
def func01():
"""
如果沒有返回值,那麼返回的是None
:return: None
"""
msg = "func01"
print(msg)
def func02():
"""
返回一個值
:return: msg
"""
msg = "func02"
print(msg)
return msg
def func03():
"""
如果返回多個值,那麼返回的是這多個值組成的元組。
實際上是返回一個值,元組。但是你可以用多個變量來接收這個元組的元素。
:return:
"""
msg = "func03"
print(msg)
return msg, [11, 22, 33], 28, "Kevin"
t1 = func01()
t2 = func02()
t3 = func03()
val, li, num, name = func03()
print(t1)
print(t2)
print(t3)
print(val, li, num, name)
# None
# func02
# ('func03', [11, 22, 33], 28, 'Kevin')
# func03 [11, 22, 33] 28 Kevin
函數的參數
參數的傳遞
函數的參數分爲實參和形參。
func04的參數xyz都是形參。形參只在函數被調用時分配內存空間,函數調用結束以後內存空間就被釋放。
函數傳參可以傳位置參數,就是按照形參順序傳參,不能多也不能少。
函數傳參可以傳關鍵字參數,就是形參名=實參,順序無所謂,不能多也不能少。
位置參數和關鍵字參數可以混搭使用。位置參數必須在關鍵字參數前面,傳參總個數不能多也不能少。
def func04(x, y, z):
print(x, y, z, sep=",")
return
# 位置參數,按照順序傳參,不能多也不能少
func04(11, 22, 33)
# 關鍵字參數,按照關鍵字傳參,順序無所謂,不能多也不能少
func04(z=33, x=11, y=22)
# 位置參數和關鍵字參數可以混用
# 位置參數 必須在 關鍵字參數 前面,不能多也不能少
func04(11, 22, z=33)
參數的默認值
函數的參數可以有默認值。非默認值參數必須放在默認值參數前面。調用時,非默認參數必須傳值,默認值參數可以不傳值。參數不用默認值時,用關鍵字參數指定哪個參數不用默認值。
def func05(app, db="mysql", os="linux"):
"""
非默認值參數放在默認值參數前面。
默認數據庫是mysql,默認操作系統是linux。
:param app: 應用
:param db: 數據庫
:param os: 操作系統
:return: None
"""
print("%(app)s, %(db)s, %(os)s." % ({"app": app, "db": db, "os": os}))
pass
# 默認值參數不用傳輸
# discuzz, mysql, linux.
func05("discuzz")
# 參數不用默認值時,最好用關鍵字參數,指定哪個參數不是默認的值
# httpd, mysql, freebsd.
func05("httpd", os="freebsd")
可變長參數
傳入多個參數,*對應列表,**對應字典。
函數參數加上*args,函數就可以接收多個位置參數,按照Python規則*args就這麼寫。*args接收位置參數,除去前面的位置參數,多出來的被處理成元組args。如果傳入的是列表,那麼列表就是元組args的一個元素。如果傳入的*列表,那麼就把列表的元素處理成元組args的元素。
def func06(x, y, *args):
"""
*args接收位置參數,將多個參數處理成元組。
此時,函數可以接收多個參數,出去前面的位置參數,後面的多個參數處理成元組
如果傳入的是個列表,那麼這個列表就是元組args的一個元素。
如果傳入的列表元素都變成args的元素,那麼傳參時需要加*。*對應列表
:param x:
:param y:
:param args:
:return:
"""
print(x)
print(y)
print(args)
pass
# 1
# 2
# ()
func06(1, 2)
# 1
# 2
# (3, 4, 5, 6)
func06(1, 2, 3, 4, 5, 6)
# 1
# 2
# ([3, 4, 5, 6],)
func06(1, 2, [3, 4, 5, 6])
1
2
(3, 4, 5, 6)
func06(1, 2, *[3, 4, 5, 6])
函數加上**kwargs,函數就可以接收多個關鍵字參數,按照Python規則就這麼寫。接收的多個關鍵字參數被處理成字典kwargs。如果要傳入字典的話,字典前面加上**。
def func07(x, y, **kwargs):
"""
*kwargs接收關鍵字參數,將多個關鍵字參數處理成字典。
此時,函數可以接收多個關鍵字參數,除去前面的位置參數,後面的多個關鍵字參數被處理成字典
如果傳入的是字典,需要在字典前面加**
:param x:
:param y:
:param kwargs:
:return:
"""
print(x, y)
print(kwargs, kwargs.get("k1"))
pass
# 1 2
# {'k1': 'v1', 'k2': 'v2'} v1
func07(1, 2, k1="v1", k2="v2")
# 1 2
# {'k1': 'v1', 'k2': 'v2'} v1
func07(1, 2, **{"k1": "v1", "k2": "v2"})
如果函數參數加上了*args和**kwargs,那麼這個函數就可以接收任意的參數了。這樣有利於未來的擴展。接收的參數怎麼處理是函數實現的問題。
def func08(x, y, *args, **kwargs):
"""
現在這個函數牛逼了
:param x:
:param y:
:param args:
:param kwargs:
:return:
"""
print(x, y)
print(args)
print(kwargs, kwargs.get("k1"))
pass
# 1 2
# (3, 4, 5, 6)
# {} None
func08(1, 2, 3, 4, 5, 6)
# 1 2
# ()
# {'a': 5, 'b': 9} None
func08(1, 2, a=5, b=9)
# 1 2
# (3, 4, 11, 22, 33, 44)
# {'k1': 'v1', 'k2': 'v2', 'k3': 9527} v1
func08(1, 2, 3, 4, *[11, 22], *[33, 44], **{"k1": "v1", "k2": "v2"}, k3=9527)
全局變量與局部變量
全局變量作用於全局。局部變量作用於代碼塊。執行函數時,先找局部變量,局部變量找不到再找全局變量。如果要直接訪問全局變量,那麼要用global聲明。Python編程規範,全局變量全部大寫,局部變量全部小寫,這樣以後就不會出現變量名重合的情況了。
name = "Kevin"
name1 = "Tom"
def change_name():
global name
name = "Alice"
name1 = "Jerry"
print(name, name1)
pass
# Alice Jerry
# Alice Tom
change_name()
print(name, name1)
函數嵌套定義
函數裏面還可以再定義函數。如果出現global,那麼global變量就是全局變量。這段代碼func12將全局變量name的值從Able改成了Charlie。
name = "Able"
def func11():
name = "Baker"
def func12():
global name
name = "Charlie"
pass
func12()
print(name)
pass
print(name)
func11()
print(name)
函數裏global只的就是全局變量,而另一個關鍵字nonlocal指的是上一層的變量。這段代碼,func12裏面將func11的局部變量name的值從Baker改爲Charlie。
name = "Able"
def func11():
name = "Baker"
def func12():
nonlocal name
name = "Charlie"
pass
func12()
print(name)
pass
print(name)
func11()
print(name)
# Able
# Charlie
# Able
風溼理論——函數即變量
Python的風溼理論?靠,什麼鬼名字。這裏的意思是函數都可以看成是函數名的字符串。只要在這個字符串裏面的變量或者函數曾經出現在內存中,就可以找到,繼續執行不會報錯。
這個例子中func14雖然定義在func13之後,但是根據風溼理論,程序逐行執行,func13和func14都會先作爲變量保存在內存中。調用func13時,執行func13代碼塊,遇到調用func14,因爲func14已經存在了,找得到,所以不會報錯。
def func13():
print("from func13")
func14()
pass
def func14():
print("from func14")
pass
# from func13
# from func14
func13()