1.值從**來
定義函式時,你可能心存疑慮:引數的值是怎麼來的呢?
編寫函式旨在為當前程式(甚至其他程式)提供服務,你的職責是確保它在提供的引數正確時完成任務,並在引數不對時以顯而易見的方式失敗。(為此,通常使用斷言或異常。)
在def語句中,位於函式名後面的變數通常稱為形參,而呼叫函式時提供的值稱為實參。
2.我能修改引數嗎
函式通過引數獲得了一系列的值,能對其進行修改嗎?如果這樣做,結果將如何?引數不過是變數而已,行為與你預期的完全相同。在函式內部給引數賦值對外部沒有任何影響。
>>> def try_to_change(n):
... n = 'mr. gumby'
...
>>> name = 'mrs. entity'
>>> try_to_change(name)
>>> name
'mrs. entity'
在try_to_change內,將新值賦給了引數n,但如你所見,這對變數name沒有影響。說到底,這是乙個完全不同的變數。傳遞並修改引數的效果類似於下面這樣:
>>> name = 'mrs. entity'
>>> n = name # 與傳遞引數的效果幾乎相同
>>> n = 'mr. gumby' # 這是在函式內進行的
>>> name
'mrs. entity'
這裡的結果顯而易見:變數n變了,但變數name沒變。同樣,在函式內部重新關聯引數(即給它賦值)時,函式外部的變數不受影響。
引數儲存在區域性作用域內。
字串(以及數和元組)是不可變的(immutable),這意味著你不能修改它們(即只能替換為新值)。因此這些型別作為引數沒什麼可說的。但如果引數為可變的資料結構(如列表)呢?
>>> def change(n):
... n[0] = 'mr. gumby'
...
>>> names = ['mrs. entity', 'mrs. thing']
>>> change(names)
>>> names
['mr. gumby', 'mrs. thing']
在這個示例中,也在函式內修改了引數,但這個示例與前乙個示例之間存在乙個重要的不同。在前乙個示例中,只是給區域性變數賦了新值,而在這個示例中,修改了變數關聯到的列表。這很奇怪吧?其實不那麼奇怪。下面再這樣做一次,但這次不使用函式呼叫。
>>> names = ['mrs. entity', 'mrs. thing']
>>> n = names # 再次假裝傳遞名字作為引數
>>> n[0] = 'mr. gumby' # 修改列表
>>> names
['mr. gumby', 'mrs. thing']
這樣的情況你早就見過。將同乙個列表賦給兩個變數時,這兩個變數將同時指向這個列表。就這麼簡單。要避免這樣的結果,必須建立列表的副本。對序列執行切片操作時,返回的切片都是副本。因此,如果你建立覆蓋整個列表的切片,得到的將是列表的副本。
>>>
names
= ['mrs. entity', 'mrs. thing']
>>>
n= names
[:]
現在n和names包含兩個相等但不同的列表。
>>>
nis
names
false
>>>
n== names
true
現在如果(像在函式change中那樣)修改n,將不會影響names。
>>> n[0] = 'mr. gumby'
>>> n
['mr. gumby', 'mrs. thing']
>>> names
['mrs. entity', 'mrs. thing']
下面來嘗試結合使用這種技巧和函式change。
>>> change(names[:])
>>> names
['mrs. entity', 'mrs. thing']
注意到引數n包含的是副本,因此原始列表是安全的。
函式內的區域性名稱(包括引數)會與函式外的名稱(即全域性名稱)衝突嗎?答案是不會。
下面來嘗試執行該程式:
>>> mynames = {}
>>> init(mynames)
>>> store(mynames, 'magnus lie hetland')
>>> lookup(mynames, 'middle', 'lie')
['magnus lie hetland']
看起來能正確地執行。下面再來嘗試幾次。
>>> store(mynames, 'robin hood')
>>> store(mynames, 'robin locksley')
>>> lookup(mynames, 'first', 'robin')
['robin hood', 'robin locksley']
>>> store(mynames, 'mr. gumby')
>>> lookup(mynames, 'middle', '')
['robin hood', 'robin locksley', 'mr. gumby']
如你所見,如果多個人的名字、中間名或姓相同,可同時獲取這些人員。
2). 如果引數是不可變的
在有些語言(如c++、pascal和ada)中,經常需要給引數賦值並讓這種修改影響函式外部的變數。在python中,沒法直接這樣做,只能修改引數物件本身。但如果引數是不可變的(如數)呢?不好意思,沒辦法。在這種情況下,應從函式返回所有需要的值(如果需要返回多個值,就以元組的方式返回它們)。例如,可以像下面這樣編寫將變數的值加1的函式:
>>> definc(x): return x + 1
...
>>> foo = 10
>>> foo = inc(foo)
>>> foo
11 如果一定要修改引數,可玩點花樣,比如將值放在列表中,如下所示:
>>> def inc(x): x[0] = x[0] + 1
...
>>> foo = [10]
>>> inc(foo)
>>> foo
[11]
但更清晰的解決方案是返回修改後的值。
python基礎常用的魔法函式
類中的初始化函式,可以顯式顯示即子呼叫類的時候以進行了函式的初始化。通過vars函式獲知顯示宣告的屬性,但是隱式的就無法獲知了,直接列印物件的實現方法,str 是被print函式呼叫的,一般都是return乙個什麼東西,這個東西應該是以字串的形式表現的。如果不是要用str 函式轉換,我們可以直接pr...
Python基礎 函式 函式引數
引數就是傳入的值 示例 usr bin env python3 coding utf 8 函式的引數和預設引數 defregist name,age,city shenzhen print name name print age age print city city 執行結果 d pythonpr...
python魔法函式
python中魔法函式簡單上來說就是在構建某個類的時候,給類定義一些初始的方法,來實現類物件的某些屬性或者方法而準備。其形式如下,下雙劃線開頭雙劃線結尾 初始化乙個學生class class student def init self,students list self.students list...