函式
為什麼要定義函式
函式分類
內建函式
自定義函式
返回值/返回函式
函式返回值
返回函式
閉包函式的引數介紹
位置引數
預設引數
可變引數
**冗餘
不方便管理,維護性差
組織結構差
def func_1():
#func_1 function
pass
print(func_1.__doc__)
用於顯示函式注釋
函式也分有參函式和無參函式,
定義時有引數,就需要傳入引數;
定義時沒有引數,就不需要傳入引數
這其中還涉及到預設引數等,在下文的引數中詳解
函式的返回值可以是任何型別
當函式沒有return ,返回的是none
這也是有些函式執行之後,會在直譯器中返回乙個none的原因
#return
def bar (x,y):
return 1,2,3
單個函式只能執行一次return,return就類似乙個break一樣,給出乙個結果並且結束程式
上面函式的返回值為乙個元組(1,2,3)
python在預設使用「,」的時候,會構建乙個元組當你需要逐個獲取返回值的時候
a,b,c = bar(x,y)
>>>
a=1b=2
c=3
以上就是一種獲取返回結果的方法,這種情況用於接收多個由函式生成的值。
範例:
a,*_,b = 'thisisastring'
a = t
b = g
有時候在函式定義完之後,發現並不需要立即傳參進行計算,而是在後面的**中,根據需要再進行計算。
這時候就可以不返回計算的結果,而是返回計算的函式:
def lazy_max():
才執行def max(a,b):
if a>b:
print(a)
elif a相關引數和變數都儲存在返回的函式中,這種稱為閉包(closure)
之前在裝飾器的筆記裡寫到過閉包,但是那時候的理解還在猜測階段,沒有乙個清晰的定義。
所以在這裡重新宣告一下:
閉包就是把相關引數和變數都儲存在返回的函式中,當乙個函式返回乙個函式後,其內部的區域性變數還被新函式引用,返回的函式也沒有立即執行,直到呼叫了()
在python中,被定義過的函式名(如果不需要傳參)後直接跟上()
就能將函式執行起來。甚至在這個函式名被賦值給其他的變數後,獲得賦值的變數也同樣有這種特性>>> def func():
… print('hello babe')
…>>> z = func
>>> z()
hello babe
在函式定義階段,括號內定義的引數,就是形參
在函式呼叫階段,括號內定義的引數,就是實參
一定要注意函式的兩個階段,定義階段不執行,不會給出結果,也不做任何操作。其實以上的定義也並不完全準確。真正的形參和實參有更加準確的描述,上述描述在例如
x=23
這種情況下就不適用,因為賦值的時候並不涉及到函式。
這個概念比較粗糙,其實大部分存在的引數,我們都可以考慮叫他位置引數(由於在python中按位置傳參的確很方便,也很普遍)。在有參函式中,如果不指定特定的關鍵字,甚至有預設的關鍵字引數,在不新增關鍵字的時候,預設按照位置引數來進行傳參。
根據位置傳值,必須在關鍵字引數前面!!!並且只能使用一種方式對同個引數進行傳值,必須進行傳值,需要準確傳值,引數不能多也不能少。
按位置傳值
比方說:
def power(x,n):
s = 1
while n>0:
n=n-1
s = s*x
return s
這是乙個修改後的power()函式,可以計算任意的n次方
這其中有兩個引數,power(x,n)
,這兩個引數都是位置引數,呼叫函式時,傳入的兩個值按照位置順序依次賦給x,n
power(5)
typeerror: power() missing 1 required positional argument: 'n'
報錯:缺少乙個引數
預設引數:呼叫時,無需傳值
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
以上**,我們在定義階段就預設定義n=2,從而在真的使用該函式的時候。當我們預設使用單個引數的時候:
>>>power(5)
25
定義函式的時候,我們使用預設引數來定義一些,變動比較小的引數,可以在傳參的時候節省力氣。
定義規則:當函式有多個引數的時候,把變化大的引數放在前面,變化小的引數放在後面
*args``**kw
def calc(number):
sum = 0
for n in number:
sum = sum+ n*n
return sum
在使用上面的函式的時候,我們傳入的num因為需要被迭代,所以num的型別必須是list或者tuple
例如calc([1,2,4,5,3,8])
如果使用可變引數,呼叫的方式就會簡單很多:calc(1,2,5,43,8)
所以我們可以修改函式定義引數為可變引數
def calc(*numbers):
pass
這裡比較需要注意的就是,位置引數和可變引數的混用。
def calc(x,y = 1,*numbers):
pass
calc(1,2,4,5,7,8,6,3,8,2,4,5)
可以發現,x,y原本是預設值,被傳參之後,取得了1,2,而剩下的數字,被作為乙個元組,合併進了numbers
>>> def calc(x,y = 1,*numbers):
… print(x)
… print(y)
… print(numbers)
…>>> calc(1,2,4,5,78,8,6,3,5)12
(4, 5, 78, 8, 6, 3, 5)
著名魯派清口導師egon曾經說過:『*』後面的可變引數,在使用的時候,就把其中的元素打散了看。
從實參的角度進行測試
>>> def bar(x,y,z):
… print(x)
… print(y)
… print(z)
…>>> bar(*(1,2,3,4))
traceback (most recent call last):
file "", line 1, in typeerror: bar() takes 3 positional arguments but 4 were given
上述我們已經使用了*args,會把後面的按位置傳值的引數整合成乙個tuple
而**kwargs,就是把後面的關鍵字傳值的引數整合成乙個dict
>>> def bar(x,y,z):
… print(x)
… print(y)
… print(z)
…>>> bar(*(1,2,3,4))
traceback (most recent call last):
file "", line 1, in typeerror: bar() takes 3 positional arguments but 4 were given
>>> def foo(x,*args,**kwargs):
… print(x)
… print(args)
… print(kwargs)
…>>>
>>>
>>> foo(1,y=3,z=5)1()
C 7 函式引數的擴充套件
int mul int x 0 int main int argc,char ar int mul int x 問題 函式定義中是否可以出現引數的預設值?當函式宣告和定義中的引數預設值不同時會發生什麼?當有函式宣告時,函式定義中不可以出現預設引數,否則編譯器報錯 當沒有函式宣告時,函式定義中可以出現...
c 第7課 函式的引數
c 在函式宣告的時候可以提供乙個預設值,必須只能在函式宣告中指定 include inta int x 1 此處為函式宣告,可以在這裡給函式提供乙個預設值 如果int x未賦乙個初始值,a 呼叫的時候一定要有引數 intmain inta int x 此處為 函式定義 不能在此處給函式提供預設值 這...
第7課 函式引數的擴充套件
a.c 中可以在函式宣告時為引數提供預設值 b.當函式呼叫時沒有提供引數的值,則使用預設值 c,引數的預設值必須在函式宣告中指定 注意 函式的預設值只能賦值一次,或是在宣告中或是在定義中 有宣告在宣告中定義,沒有時可在定義中定義 a.引數的的預設值必須從右向左提供 函式呼叫時從左向右匹配 b.函式呼...