函數(shù)
函數(shù)是可重復使用的程序片段:它允許你為 某個代碼塊 命名,允許通過這一特殊的名字在你程序的任何地方來運行代碼塊,并可重復使用。這就是所謂的“調用”函數(shù)(calling)。(我們已經使用過很多內置函數(shù),比如len和range)
函數(shù)可以通過關鍵字def來定義。這一關鍵字后面跟一個函數(shù)的標識符名稱,再跟一對括號,括號內可以包括一些變量的名稱,再以冒號結尾,結束這一行;隨后的語句塊是函數(shù)的一部分。
def say_hello(): #下面這一代碼塊屬于這一函數(shù) print('hello world') say_hello() #調用函數(shù) say_hello() #再次調用函數(shù)
輸出為:
hello world hello world
這個函數(shù)不使用參數(shù),因此在括號里面沒有聲明變量
函數(shù)參數(shù)
def print_max(a, b): if a > b: print(a, "is maximum") elif a == b: print(a, "is equal to", b) else: print(b, "is maxmum")
print_max(3, 4) 4 is maximum
x = 3 y = 8 print_max(x, y) 8 is maximum
函數(shù)可以獲取參數(shù),參數(shù)由你來提供,借此函數(shù)便可以來利用這些參數(shù)做一些事情。
這些參數(shù)和變量類似:這些變量的值在我們調用函數(shù)的時候已經被定義,且在函數(shù)運行時均已賦值完成
函數(shù)的參數(shù)在用以定義函數(shù)的( )中指定,用逗號隔開; 當我們調用函數(shù)時,需要以同樣的形式提供所需的值——注意,在定義函數(shù)時給定的參數(shù)名稱叫做“形參”(parameters)(如上面例子中的a和b; 在你調用函數(shù)的時候你所提供給函數(shù)的括號里面的值叫做“實參”(arguments)(如上例中的3,4; x, y)
上例工作方式:
將函數(shù)命名為print_max并且提供兩個形參,分別為a和b; 第一次調用函數(shù)時,直接以實參的形式向函數(shù)提供兩個數(shù)字,3和4; 第二次調用函數(shù)時,將變量(x,y)作為實參提供給函數(shù),使得實參x,y的值被賦給了形參a,b。
局部變量
x = 50 def func(x): print('x is', x) x = 2 print('changed local x to', x) func(x) print('out of the func, x is still', x)
輸出為:
x is 50 changed local x to 2 out of the func, x is still 50
上例工作方式:
在第一次打印x時,使用的是函數(shù)聲明之上,主代碼塊中的聲明的x這一實參的值;第二次打印x時,x已經被賦值為2,但是這一實參是這一函數(shù)的局部變量——我們在改變函數(shù)中x的值的時候,外部主代碼塊中的x的值是不受影響的;因此最后一句print依然打印出主代碼塊中x的值。
當你在一個函數(shù)的定義中聲明變量時,它們不會以任何形式和函數(shù)代碼塊之外的、具有相同名稱的變量產生關系——因為函數(shù)中的變量名只存在于函數(shù)這一局部(local),這被稱為函數(shù)的作用域(scope)。所有函數(shù)的作用域是它們被定義的塊,從它們名字的定義點開始。
global語句
x = 50 def func(): global x print('now x is", x) x = 2 print('changed global x to', x) func() print('now the value of x is', x)
輸出為:
now x is 50 changed global x to 2 now the value of x is 2
上例工作方式:
global語句聲明x是一個全局變量——因此在函數(shù)中給x賦值為2時,將會影響到主代碼中x的值。
你可以在同一global語句中指定不止一個全局變量:global x, y , z
如果你想給一個程序頂層的變量賦值(也即是這一變量不存在于任何作用域中,無論是函數(shù)還是類),那么你必須告訴Python這一變量不是局部的,而是全局的(global)。
默認參數(shù)值
對于一些函數(shù)來說,你可能希望一些參數(shù)可選并且使用默認的值,以避免用戶不想提供值的情況。 你可以通過函數(shù)定義時附加一個賦值運算符(=)來為參數(shù)指定一個默認值。注意默認值是常數(shù)(constant),確切地說,默認參數(shù)值是不可變的。
def say(message, times = 1): print(message * times) say('hello ') say('world ', 5)
輸出為:
hello world world world world world
上例工作方式:
say函數(shù)用以按照給定的次數(shù)打印一串字符串。如果用戶沒有提供一個數(shù)值,那么則按照默認設置,只打印一次,這通過給參數(shù)times設定默認參數(shù)值1來實現(xiàn)。
第一次調用say函數(shù)時,用戶只提供了字符串,因此字符串只打印一次。第二次調用時,既提供了字符串,又提供了參數(shù)5,聲明用戶希望打印5次message。
注意:只有位于參數(shù)列表末尾的參數(shù)才能被賦予默認參數(shù)值
關鍵字參數(shù)(keyword arguments)
如果你有一些具有許多參數(shù)的函數(shù),而你又只希望對其中的一些進行指定,那么你可以通過命名它們來給參數(shù)賦值 --這就是關鍵字參數(shù)(keyword arguments)--我們使用命名,而非位置,來指定函數(shù)中的參數(shù)。
這種做法有兩大有點:其一是,我們不需要考慮參數(shù)的順序,函數(shù)的使用會更容易;其二是,我們可以只對那些我們希望賦值的參數(shù)賦值,只要其他參數(shù)都具有默認參數(shù)值。
def func(a, b=5, c=10): print('a is', a, 'and b is',b, 'and c is', c) func(3, 7) func(25, c=24) func(c=50, a=100)
輸出為:
a is 3 and b is 7 and c is 10
a is 25 and b is 5 and c is 24
a is 100 and b is 5 and c is 50
工作方式:
名為func的函數(shù)有一個沒有默認值的參數(shù),后邊兩個參數(shù)有默認值。
第一次調用函數(shù)func時,func(3, 7)使得a獲得了3的值,b獲得了7的值,而c獲得默認參數(shù)值10。
第二次調用函數(shù)func時,func(25, c=24),由于位置,a首先獲得25的值;由于命名(既關鍵字參數(shù)指定),c獲得24的值。b獲得默認值5。
第三次調用函數(shù)時,全部用關鍵字參數(shù)來指定值。
可變參數(shù)
如果你想讓你定義的函數(shù)里有任意數(shù)量的變量(即是參數(shù)數(shù)量是可以改變的),可以通過使用星號來實現(xiàn)。
當我們聲明一個諸如*param的星號參數(shù)時,從此處開始到結束所有的位置參數(shù)(positional arguments)都將被收集并匯集成一個名為param的元組(tuple)
當我們聲明一個諸如**param的雙星號參數(shù)時,從此處開始到結束所有的關鍵字參數(shù)(keyword arguments)都將被收集并匯集成一個稱為param的字典(dictionary)
后續(xù)章節(jié)會繼續(xù)介紹元組和字典。
def total(a = 5, *numbers, **phonebook): print('a', a) #遍歷元組中所有項目 for single_item in numbers: print('single_item', single_item) 遍歷字典中所有項目 for first_part, second_part in phonebook.items(): print(first_part, second_part) print(total(10, 1, 2, 3, jack = 1123, john = 2231, inge = 1560))
輸出為:
a 10
single_item 1
single_item 2
single_item 3
jack 1123
john 2231
inge 1560
return語句
return用于從函數(shù)中返回,也就是中斷函數(shù)
def maximum(x,y): if x > y: return x elif x == y; return 'the numbers are euqal' else: return y print(2,3)
輸出為:
3
注意,如果return語句沒有搭配任何一個值則返回none。 none在py中是一個特殊類型,代表“虛無”,用于指示一個變量沒有值,如果有值,值便是none(虛無)。
每個函數(shù)都在其末尾隱含了一句return None,除非你寫了自己的return語句。
DocStrings:Py的文檔字符串
我們可以通過一個函數(shù)來獲取文檔:
def print_max(x, y): '''打印這兩個數(shù)值中的最大值 這兩個數(shù)都應該是整數(shù)''' #將x和y轉化為整數(shù)類型 x = int(x) y = int(y) if x > y: print(x) elif x == y: print('equal') else: print(y) print_max(2,3) print(print_max.__doc__)
輸出為:
3
打印這兩個數(shù)值中的最大值
這兩個數(shù)都應該是整數(shù)
函數(shù)的第一邏輯行中的字符串是該函數(shù)的“文檔字符串(DocStrings)”,文檔字符串不僅適用于函數(shù),也適用于后邊章節(jié)提到的模塊(modules)和類(class);
該文檔字符串約定的是一串多行字符,第一行以某大寫字母開始,以句號結束;第二行為空行;第三行開始是任何詳細的解釋說明。強烈建議在所有重要功能的所有文檔字符串都遵守這一約定。
我們通過使用函數(shù)的doc屬性來獲取函數(shù)的文檔字符串。
強烈推薦給所有重要函數(shù)配備文檔字符串