Python-2 函式、引數
阿新 • • 發佈:2020-12-05
函式
help(abs)
:檢視函式 abs 的幫助資訊pass
:佔位符,還沒想好怎麼寫,先pass
,讓程式跑起來看一下。- 比如在 if 語句下,定義函式如下。
def my_abs(x): if not isinstance(x, (int, float)): raise TypeError('bad operand type') if x >= 0: return x else: return -x
- 定義函式下,第一行使用:
"函式的說明註釋"
。 - Python 可以返回多個值,
return x, y
- 接收:
x, y = test(xxx)
- 返回的其實是一個元組,多個變數接收一個元組,則元組將元素按順序賦值給變數
isinstance(x, (int, float))
:x
是否為 int 或 float 型別
reise TypeError('錯誤提示文字')
:丟擲型別錯誤- 不同於 java ,Python 可以有預設引數,可寫成
def power(x, n=2)
,此時呼叫power(5)
,相當於power(5, 2)
- 預設引數為可變型別的陷阱:
有一函式 drf x(L[])
:多次呼叫 x()
(不傳引數,使用預設引數),則會發現這個預設引數被存下來了。
def add_end(L=[]): L.append('END') return L
>>> add_end()
['END']
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
def
中,預設引數被定義了,擁有了一個記憶體地址。直接呼叫預設引數的話(沒給引數),會對該地址進行操作,導致該預設引數被改變了。
所以應該儘量使預設引數為不可變引數。
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
- 這裡,
def
- 函式的不加任何東西的引數預設是位置引數(必須引數),不可缺少。
- 可批量代入引數:將一個元組/列表,使用
*
當做引數的合體傳入函式:
def computed(x, y):
print(x, y)
x = [1, 1] # 或者:x = (1, 1)
computed(*x)
- 函式內可以再定義函式,並且這個內部函式可以訪問外部函式的引數和區域性變數。
可變引數
定義可變引數的函式(java 裡的 ...
):
def calc(*numbers)
- 可變引數
numbers
在函式裡被合併為一個元組,在外面呼叫函式直接傳進來多個值即可。 - 呼叫函式時,也可以使用:
calc(*tuple1)
,直接將一個元組/列表作為引數。
def computed(x, y, *z):
print("可變引數:", z)
print(x, y)
x = [1, 1, 2, 2]
computed(*x, **n)
可變引數: (2, 2)
1 1
關鍵字引數
關鍵字引數 **kw
相當於可變引數 *args
的變種,也是一種可選的,但是它是鍵值對形式。
def person(name, age, **kw):
kw
是 字典,鍵值對;name
,age
稱為位置引數name
,age
是必要的,而關鍵字引數是次要的,擴充套件的。- 呼叫:
person('Bob', 18, city='Xiamen', job='ceo')
,必須傳入引數名,否則會被識別為位置引數,出現錯誤。 - 同樣,呼叫函式時使用
person('Bob', 18, **extra)
,將一個名為extra
的字典做為引數傳入。
- 值得注意的是,這裡的
**extra
只是extra
的一個淺拷貝,函式內的對不可變元素的操作不會影響外部的extra
,但操作可變元素有影響。
在呼叫函式時,使用如:x(age=12)
,可以僅傳入一個年齡的引數,不會是 name
的值。
命名關鍵字引數:限制關鍵字引數的名字
def person(name, age, *, city='Beijing', job): # 在星號後面寫上關鍵字引數應有的鍵名
這裡除必須引數外,還限制必須要有且僅有名為 city
,job
的引數傳進來。
- 如果有可變引數,可變引數後面的關鍵字引數可以不再用
*
分隔了,後面預設是關鍵字引數:def person(name, age, *args, city, job)
- 如果關鍵字引數有預設值,則可以不用必須傳入
- 比如這樣可以呼叫上面小標題下的函式:
person('Jack', 24, job='Engineer')
- 比如這樣可以呼叫上面小標題下的函式:
強制位置引數
在上面的引數中的,呼叫時:
- 如
f(10)
使用的是位置引數,沒有,是沒有帶名字的引數 f(a = 10)
使用的是關鍵字引數/命名關鍵字引數,帶有名字
Python 3.8 新增了一種引數 /
,使得前面的引數呼叫必須使用位置引數:
def f(a, b, /, c, d, *, e, f)
print(a, b, c, d, e, f)
以下使用方法是正確的:
f(10, 20, 30, d=40, e=50, f=60)
以下使用方法會發生錯誤:
f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用關鍵字引數的形式
f(10, 20, 30, 40, 50, f=60) # e 必須使用關鍵字引數的形式
引數組合
有多種引數的話,按照邏輯以及要求,必須按順序來:必選引數(位置引數)、預設引數、可變引數、命名關鍵字引數和關鍵字引數。
def f2(a, b, c=0, *, d, **kw)
# 必 必 默 命名 關鍵
# f2函式要有a,b,可選c引數,還必須要有d=value
# 因為有**kw,所以還可有其他帶名字的鍵值對傳入
對於任意函式,都可以通過類似 func(*args, **kw)
的形式呼叫它,無論它的引數是如何定義的。
*args
囊括必選引數、預設引數、可變引數**kw
囊括命名關鍵字引數、關鍵字引數
遞迴函式
解決遞迴呼叫棧溢位的方法:尾遞迴
大多數程式語言沒有針對尾遞迴做優化,Python直譯器也沒有做優化,所以,即使把階乘的 fact(n)
自定義函式改成尾遞迴方式,也會導致棧溢位。
匿名函式
lambda 表示式,它是一個表示式,只包含一個語句,而不是一個程式碼塊。僅僅能在lambda表示式中封裝有限的邏輯進去。
lambda [arg1 [,arg2,.....argn]]:expression
# 冒號前引數,冒號後表示式
示例:
sum = lambda arg1, arg2: arg1 + arg2
# 呼叫sum函式
print("相加後的值為: ", sum(10, 20))
print("相加後的值為: ", sum(20, 20))