1格式:
deffunctionName(參數列表):
方法體
例子1:
>>>def greet_user(): print(“hello”) >>>greet_user() hello
例子2:
>>>def greet_user(username): #username形參 print(“hello,”+ username+“!”) >>>greet_user(“zhangsan”) #zhangsan 實參 hello, zhangsan!
2傳遞實參
鑑於函數定義中可能包含多個形參,因此在函數調用中也可能包含多個實參。向函數中傳遞實參的方式很多,可以使用位置實參,這要求實參的順序和形參的順序相同;也可以使用關鍵字形參,其中的每個實參都有變量名和值組成;還可以使用列表和字典。
(1)位置實參
要求實參的順序和形參的順序相同
例子:
def describe_pet(animal_type,pet_name): print(“\n I have a”+animal_type+”.”) print(“My ”+animal_type+”’sname is ”+pet_name+”.”) describe_pet(‘hamster’,’harry’)
當兩個參數的位置交換後,表達的意思就會出現錯誤。
這種傳參方式應該是最好理解的,大部分語言都是這種傳參方式。
(2)默認參數
編寫函數時,可給每個形參指定默認值。在調用函數中給形參提供了實參時,Python將使用指定實參,否則使用默認值。
def describe_pet(pet_name,animal_type=‘dog’): print(“\n I have a ”+animal_type+”.”) print(“My ”+animal_type+”’sname is ”+pet_name+”.”
注意:在使用默認參數時,在形參列表中必須先列出沒有默認值的形參,再列出有默認值的形參。
當然,默認值不一定是字符串,數字等,同時也支持各種序列。
def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print(f(3))
輸出結果爲
[1] [1, 2] [1, 2, 3]
如果你不想調用之間共享的默認設置,你可以這樣寫
def f(a, L=None): if L is None: L = [] L.append(a) return L
感覺有點像java中單例模式中的懶漢式,雖然不能這麼比。
(3)關鍵字實參
關鍵字實參是傳遞給函數的 名稱-值對。你直接在實參中將名稱和值關聯起來,因此向函數傳遞實參時不會混淆
def parrot(voltage, state='a stiff', action='voom',type='Norwegian Blue'): print("--This parrot wouldn't", action, end=' ') print("ifyou put", voltage, "volts through it.") print("--Lovely plumage, the", type) print("--It's", state, "!")
parrot(1000) # 1positional argument parrot(voltage=1000) # 1 keywordargument parrot(voltage=1000000,action='VOOOOOM') # 2 keywordarguments parrot(action='VOOOOOM',voltage=1000000) # 2 keywordarguments parrot('amillion', 'bereft of life', 'jump') # 3 positional arguments parrot('athousand', state='pushing up the daisies') # 1 positional, 1 keyword
執行後的結果
>>> ===========RESTART: D:/python/pythonLearning/KeywordArguments.py =========== -- This parrotwouldn't voom if you put 1000 volts through it. -- Lovelyplumage, the Norwegian Blue -- It's a stiff! -- This parrotwouldn't voom if you put 1000 volts through it. -- Lovelyplumage, the Norwegian Blue -- It's a stiff! -- This parrotwouldn't VOOOOOM if you put 1000000 volts through it. -- Lovelyplumage, the Norwegian Blue -- It's a stiff! -- This parrotwouldn't VOOOOOM if you put 1000000 volts through it. -- Lovelyplumage, the Norwegian Blue -- It's a stiff! -- This parrotwouldn't jump if you put a million volts through it. -- Lovelyplumage, the Norwegian Blue -- It's bereftof life ! -- This parrotwouldn't voom if you put a thousand volts through it. -- Lovelyplumage, the Norwegian Blue -- It's pushingup the daisies !
但是下面的調用方式會報錯:
parrot() # 必須的參數沒有填入
parrot(voltage=5.0, 'dead') # 關鍵字傳參後面的一定也是關鍵字傳參
parrot(110, voltage=220) # 同一個參數傳了不同的實參
parrot(actor='John Cleese') # 函數定義中沒有這個形參。
關鍵字實參後面不能再有位置實參。
當必填參數沒有時,會報錯。
當必填參數以位置實參的方式傳遞時,默認參數可以按照關鍵字實參的方式傳遞,也可以以位置實參的方式傳遞,而且此時,必填參數一定在默認參數前面。
當必填參數以關鍵字實參方式傳遞的時候,默認參數傳遞的時候也一定是以關鍵字實參方式傳遞,而且此時與位置無關。
關鍵字實參的關鍵字必須是形參中有的,否則會報錯。
(4)任意多數目的參數“*”
最不常使用的選項是指定可以使用任意數量的參數調用的函數。這些參數將被裹在一個元組中。在可變數目的參數之前, 零個或更多的正常參數可能會發生。
def write_multiple_items(file, separator, *args): file.write(separator.join(args))
通常情況下,可變參數將在參數列表中的最後(含有默認參數的時候,默認參數在可變參數後面。另外,傳入字典參數也在可變參數之後,因爲字典參數也是一種可變參數)。
在可變參數後面的參數,只能以關鍵字實參的方式傳遞,而不能使用位置實參傳遞方式。
def concat(*args, sep="/"): return sep.join(args) print(concat("earth", "mars", "venus")) print(concat("earth", "mars", "venus",sep="."))
結果爲:
>>> ===========RESTART: D:/python/pythonLearning/KeywordArguments.py =========== earth/mars/venus earth.mars.venus
(5)需要字典類型的參數“**”
下面例子中**keywords代表傳入字典類型的參數,而且*一定要在**之前。
def cheeseshop(kind, *arguments, **keywords): print("--Do you have any", kind, "?") print("--I'm sorry, we're all out of", kind) for arg inarguments: print(arg) print("-" * 40) keys =sorted(keywords.keys()) for kw in keys: print(kw,":", keywords[kw])
可以這樣調用
cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.", shopkeeper="Michael Palin", client="John Cleese", sketch="Cheese Shop Sketch")
當然結果如下:
>>> ===========RESTART: D:/python/pythonLearning/KeywordArguments.py =========== -- Do you haveany Limburger ? -- I'm sorry,we're all out of Limburger It's very runny,sir. It's reallyvery, VERY runny, sir. ---------------------------------------- client : JohnCleese shopkeeper :Michael Palin sketch : CheeseShop Sketch
(6)Unpacking Argument Lists(python3.6幫助文檔上用的這個詞,必應翻譯給的翻譯是開箱的參數列表,我感覺應該是參數列表的拆包,不夠下面還是用了開箱這個詞,大家理解下)
這是與之前把數據組合成list相反的操作,即把list中的數據進行開箱操作,把裏面的數據全部取出來使用,有點不好理解,看個例子吧
>>> list(range(3,6)) [3, 4, 5] >>> args=[3,6] >>> list(range(*args)) [3, 4, 5] >>> args=(3,6) >>> list(range(*args)) [3, 4, 5] >>>
這裏把args中的數據進行開箱操作,把裏面的數據作爲range的參數列表.很顯然,這個開箱操作對於元組也是適用的.
另外,也可以對字典執行開箱操作,需要的是兩個*號即可.
def parrot(voltage, state='a stiff',action='voom'): print("-- This parrot wouldn't", action, end=' ') print("if you put", voltage, "volts through it.", end='') print("E's", state, "!") d = {"voltage": "fourmillion", "state": "bleedin' demised","action": "VOOM"} parrot(**d)
結果爲:
>>> =========== RESTART:D:/python/pythonLearning/KeywordArguments.py =========== -- This parrot wouldn't VOOM if you putfour million volts through it. E's bleedin' demised !
>>>
(7)lambda表達式
可以使用 lambda 關鍵字創建小的匿名函數。此函數返回其兩個參數的總和 lambda a, b:a + b
Lambda 函數可以用於任何函數對象。他們在語法上限於單個表達式。語義上,他們都只是正常的函數定義的語法糖。嵌套的函數定義類似,lambda 函數可以從包含範圍引用變量。(之後的文章會詳細講解lambda表達式的相關操作)
def make_incrementor1(n): return lambdax:x+n f=make_incrementor1(42) print(f(1)) >>> =========== RESTART:D:/python/pythonLearning/KeywordArguments.py =========== 43 >>>
(8) Function Annotations函數註解
首先是一個簡單的例子
def f(ham:str,eggs:str='eggs2')->str: print("Annotations:",f.__annotations__) print("Arguments:",ham,eggs) return str(ham)+' and ' +eggs s=f(‘abc’) print(s)
結果:
>>> =========== RESTART:D:/python/pythonLearning/KeywordArguments.py =========== Annotations: {'ham': <class 'str'>,'eggs': <class 'str'>, 'return': <class 'str'>} Arguments: abc eggs2 abc and eggs2 >>>
函數註解是完全可選的元數據信息,它告訴人們這個函數返回的類型應該是什麼類型,函數形參應該是什麼類型。但是傳入其他類型可能會報錯,當然,這並非絕對,只不過是開發者給調用者的一個建議。上面的例子中,即使實參傳入數字也是不會報錯的。(這段在python3.6幫助文檔上的說明看得我很頭疼,比較亂,我領會精神寫的)
註解存儲在 __annotations__ 屬性中,以字典的形式存在,對其他部分的功能沒有任何影響。
參數註釋:在參數名稱的後面加一個冒號,其後是期待實參的類型。
返回值註解:函數的參數列表外面,冒號前面,加上一個 –>,後面是期待返回的類型。