python定义函数的组成部分有_Python文档学习笔记(4)--定义函数
定義函數
關鍵字 def 引入函數的定義。其后必須跟有函數名和以括號標明的形式參數列表。組成函數體的語句從下一行開始,且必須縮進。
執行 一個函數會引入一個用于函數的局部變量的新符號表。
因此,在函數內部無法給一個全局變量直接賦值(除非在一個 global 語句中命名),雖然可以引用它們。
return 語句可以從函數中攜帶著返回值返回。return 語句不攜帶任何表達式參數時返回 None。如果一直執行到整個函數結束還沒有碰到 return 語句,也返回 None。
a =0
b=0def A(a): #定義函數
print("函數內引用a:{}".format(a)) #可以引用
a = 1
global b #全局聲明后可以修改
b = 1
print("函數內a:{}".format(a))print("函數內b:{}".format(b))return a #return 函數的返回值,沒有return返回None
r=Aprint("函數外a:{}".format(a))print("函數外b:{}".format(b))print("return:{}".format(r(a)))################
函數內引用a:0
函數內a:1函數內b:1函數外a:0
函數外b:1
return:1
默認參數值
這個函數可以通過幾種方式調用:
只提供必須的參數: ask_ok('Do you really want to quit?')
提供可選參數中的一個: ask_ok('OK to overwrite the file?', 2)
或者提供所有參數: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
def ask_ok(prompt, retries=4, reminder='Please try again!'):whileTrue:
ok=input(prompt)if ok in ('y', 'ye', 'yes'):returnTrueif ok in ('n', 'no', 'nop', 'nope'):returnFalse
retries= retries - 1
if retries <0:raise ValueError('invalid user response')print(reminder)
默認值在函數定義的時刻,在定義的作用域中計算(函數內定義域)
i = 5
def f(arg=i):print(arg)
i= 6f()
默認值只初始化一次。當默認值是一個可變對象(如列表,字典或大多數類的實例)時,默認值會不同。例如,下面的函數在后續調用過程中會累積傳給它的參數:
def f(a, L=[]):
L.append(a)returnLprint(f(1))print(f(2))print(f(3))#########
[1]
[1, 2]
[1, 2, 3]
如果你不想默認值在隨后的調用中共享,可以像這樣編寫函數:
def f(a, L=None):if L isNone:
L=[]
L.append(a)return L
關鍵字參數
函數還可以用kwarg=value形式的關鍵字參數調用。例如,下面的函數:
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):print("-- This parrot wouldn't", action, end=' ')print("if you put", voltage, "volts through it.")print("-- Lovely plumage, the", type)print("-- It's", state, "!")
在函數調用中,關鍵字參數必須寫在位置參數之后。傳遞的所有關鍵字參數必須匹配函數接收的參數中的一個(例如,actor不是parrot函數的合法參數),它們的順序并不重要。這同樣適用于非可選的參數(例如,parrot(voltage=1000)也是合法的)。任何參數都不可以多次賦值。
接受一個必需的參數 (voltage) 和三個可選參數 (state, action, and type)。可以用下列任意一種方式調用這個函數:
parrot(1000) #1 positional argument
parrot(voltage=1000) #1 keyword argument
parrot(voltage=1000000, action='VOOOOOM') #2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000) #2 keyword arguments
parrot('a million', 'bereft of life', 'jump') #3 positional arguments
parrot('a thousand', state='pushing up the daisies') #1 positional, 1 keyword
如果在最后存在一個**name形式的形式參數,它將接收一個字典(參見映射類型——字典),這個字典包含除形式參數之外的所有關鍵字參數。它可以與*name形式的形式參數組合(在下一節講述),這種形式接收一個元組,這個元組包含除形式參數之外的所有位置參數。(*name必須出現在**name之前)。例如,如果我們定義這樣的函數:
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 inkeys: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")#########
--Do you have any Limburger ?-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
*arguments:"It's really very, VERY runny, sir."
**keywords : shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch"
任意參數的列表
某個函數可以被可變個數的參數調用。這些參數將被封裝在一個元組中(參見元組和序列)。在可變數量的參數之前,可能出現零個或多個正常參數。
通常,這些可變的參數將位于形式參數列表的最后面,因為它們將剩下的傳遞給函數的所有輸入參數都包含進去。出現在*args之后的任何形式參數都是“非關鍵字不可”的參數,意味著它們只能用作關鍵字參數而不能是位置參數。
>>> def concat(*args, sep="/"):
...returnsep.join(args)
...>>> concat("earth", "mars", "venus")'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")'earth.mars.venus'
解包參數列表
當傳遞的參數已經是一個列表或元組時,情況與之前相反,你要分拆這些參數,因為函數調用要求獨立的位置參數。例如,內建的range()函數期待單獨的start和stop參數。如果它們不能單獨地獲得,可以編寫帶有*操作的函數調用,來從一個列表或元組分拆出參數:
>>> list(range(3, 6)) #normal call with separate arguments
[3, 4, 5]>>> args = [3, 6]>>> list(range(*args)) #call with arguments unpacked from a list
[3, 4, 5]
同樣的風格,字典可以通過**操作傳遞關鍵字參數:
>>> 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": "four million", "state": "bleedin' demised", "action": "VOOM"}>>> parrot(**d)-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin'demised !
Lambda 表達式
可以使用 lambda關鍵字創建小的匿名函數。此函數會返回兩個參數的總和: lambda a, b: a+b.。Lambda 函數可以用于任何需要函數對象的地方。在語法上,它們被局限于只能有一個單獨的表達式。在語義上,他們只是普通函數定義的語法糖。像嵌套的函數定義,lambda 函數可以從包含它的作用域中引用變量:
>>> defmake_incrementor(n):
...return lambda x: x +n
...>>> f = make_incrementor(42)>>>f(0)42
>>> f(1)43
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]>>> pairs.sort(key=lambda pair: pair[1])>>>pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
文檔字符串
下面是一些關于文檔字符串內容和格式的慣例
第一行永遠應該是對象用途的簡短、精確的總述。為了簡單起見,不應該明確的陳述對象的名字或類型,因為這些信息可以從別的途徑了解到(除非這個名字碰巧就是描述這個函數操作的動詞)。這一行應該以大寫字母開頭,并以句號結尾。
如果在文檔字符串中有更多的行,第二行應該是空白,在視覺上把摘要與剩余的描述分離開來。以下各行應該是一段或多段描述對象的調用約定、 其副作用等。
Python 解釋器不會從多行的文檔字符串中去除縮進,所以必要的時候處理文檔字符串的工具應當自己清除縮進。使用以下約定即可,第一行 之后 的第一個非空行字符串確定整個文檔字符串的縮進的量。(我們不用第一行是因為它通常緊靠著字符串起始的引號,其縮進格式不明晰。)所有行起始的等于縮進量的空格都將被過濾掉。不應該存在縮進更少的行,但如果確實存在,應去除所有其前導空白。應該在展開制表符之后(展開后通常為8個空格)再去測試留白的長度。
>>> defmy_function():
..."""Do nothing, but document it.
...
... No, really, it doesn't do anything.
..."""...pass...>>> print(my_function.__doc__)
Do nothing, but document it.
No, really, it doesn't do anything.
函數注解
函數注解是關于用戶定義的函數使用的類型的元數據信息,它們是完全可選的(更多信息參見
注解以字典形式存儲在函數的__annotations__屬性中,對函數其它任何部分沒有任何影響。參數注解的定義是參數名后面跟著一個冒號,然后緊跟著一個用于計算注解的表達式。返回值注解的定義是一個->然后緊跟著一個表達式,它們位于參數列表和表示def語句結束的冒號之間。下面的示例包含一個位置參數,一個關鍵字參數,和被注解的返回值。
>>> def f(ham: str, eggs: str = 'eggs') ->str:
...print("Annotations:", f.__annotations__)
...print("Arguments:", ham, eggs)
...return ham + 'and' +eggs
...>>> f('spam')
Annotations: {'ham': , 'return': , 'eggs': }
Arguments: spam eggs'spam and eggs'
代碼風格
若要編寫更長更復雜的 Python 代碼,是時候談一談 編碼風格了 。大部分語言都可以有多種(比如更簡潔,更格式化)寫法,有些寫法可以更易讀。讓你的代碼更具可讀性,而良好的編碼風格對此有很大的幫助。
對Python, PEP 8 已經成為多數項目遵循的代碼風格指南;它推動了一種非常易于閱讀且賞心悅目的編碼風格。每個Python開發者都應該找個時間讀一下; 以下是從中提取出來的最重要的一些點:
使用 4 個空格的縮進,不要使用制表符。
4 個空格是小縮進(允許更深的嵌套)和大縮進(易于閱讀)之間很好的折衷。制表符會引起混亂,最好棄用。
折行以確保其不會超過 79 個字符。
這有助于小顯示器用戶閱讀,也可以讓大顯示器能并排顯示幾個代碼文件。
使用空行分隔函數和類,以及函數內的大塊代碼。
如果可能,注釋單獨成行。
使用文檔字符串。
在操作符兩邊和逗號之后加空格, 但不要直接在左括號后和右括號前加: a = f(1, 2) + g(3, 4).
類和函數的命名風格要一致;傳統上使用 CamelCase (駝峰風格)命名類 而用 lower_case_with_underscores(小寫字母加下劃線)命名函數和方法。方法的第一個參數名稱應為 self (查看 初識類 以獲得更多有關類和方法的規則)。
如果您的代碼要在國際環境中使用,不要使用花哨的編碼。Python 默認的 UTF-8 或者 ASCII 在任何時候都是最好的選擇。
同樣,只要存在哪怕一丁點可能性有使用另一種不同語言的人會來閱讀或維護你的代碼,就不要在標識符中使用非 ASCII 字符。
總結
以上是生活随笔為你收集整理的python定义函数的组成部分有_Python文档学习笔记(4)--定义函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python discuz_python
- 下一篇: python变量类型是动态的_Pytho