python之函式總結

2021-10-21 08:25:52 字數 3758 閱讀 3105

目錄

1.盡量用異常來表示特殊情況,而不要返回 none

2.了解如何在閉包裡使用外圍作用域中的變數

2.1閉包相關介紹

2.2獲取閉包內的資料 —— nonlocal語句

3. 考慮用生成器來改寫直接返回列表的函式

4.用數量可變的位置引數減少視覺雜訊

5.用關鍵字引數來表達可選的行為

6.用 none 和文件字串來描述具有動態預設值的引數

7.用只能以關鍵字形式指定的引數來確保**清晰

用 none 這個返回值來表示特殊意義的函式,很容易使呼叫者犯錯,因為none 和 0 以及空字串之類的值,在表示式裡都會評估為 false。

函式在遇到特殊情況時,應該丟擲異常,而不要返回 none 。呼叫者在看到該函式的文件中所描述的異常之後,應該就會編寫相應的**來處理它們了。

def divide(a, b):

try:

return a / b

except zerodivisionerror as e:

raise valueerror('invalid inputs') from e # 丟擲異常

x, y = 5, 2

try:

result = divide(x, y)

except valueerror:

print('invalid inputs')

else:

print('result is %.lf' % result)

我們可以將閉包理解為一種特殊的函式,這種函式由兩個函式的巢狀組成,且稱之為外函式和內函式,外函式返回值是內函式的引用,此時就構成了閉包。

def 外層函式(引數):

def 內層函式():

print("內層函式執行", 引數)

return 內層函式

內層函式的引用 = 外層函式("傳入引數")

內層函式的引用()

參考:

1)python比較兩個元組:首先比較各元組中下標為0(第乙個)的對應元素,如果相等,再比較下標為1的對應元素...列表比較也類似。

2)在表示式中引用變數時,python直譯器將按如下順序遍歷各作用域,以解析該引用:

當前函式的作用域。

任何外圍作用域(如:包含當前函式的其他函式)。

包含當前**的那個模組的作用域(即全域性作用域,global scope)。

內建作用域(即包含len 及 str 等函式的那個作用域)。

如果上面這些地方都沒有定義過與名稱相符的變數,就丟擲 nameerror 異常。

nonlocal:在閉包內給變數賦值,會在上層作用域中查詢該變數,在閉包內修改的其實是閉包外那個作用域的變數。nonlocal的唯一限制在於,它不能延申到模組級別。除了那種簡單的函式,盡量不要用 nonlocal 語句,應該將相關狀態封裝成輔助類,也可以利用上面的變數搜尋規則,將變數改為列表型別: 變數名[0] = ?(字典,集合,某個類的例項也類似)。

global:用來表示對該變數的賦值操作,將會直接修改模組作用域裡那個變數。

生成器(generator)是使用 yield 表示式的函式,呼叫生成器函式時,它並不會真正的執行,而是會返回迭代器。每次在這個迭代器上面呼叫內建的 next 函式時,迭代器會把生成器推進到下乙個 yield 表示式那裡。生成器傳給yield的每乙個值,都會由迭代器返回給呼叫者。

例,查出字串中每個詞的首字母在整個字串裡的位置。

def index_file(handle):

offset = 0

# 從檔案裡依次讀入各行內容

for line in handle:

if line:

yield offset

# 逐行處理每個單詞

for letter in line:

offset += 1 # 指向letter後乙個位址

if letter == ' ':

yield offest

with open('filepath', 'r') as f:

it = index_file(f)

results = islice(it, 0 , 3) # 迭代前三個

print(list(result))

islice(iterable, [start, ] stop [, step]):

建立乙個迭代器: iterable[start : stop : step],跳過前start個項,迭代在stop所指定的位置停止,step指定用於跳過項的步幅。迭代預設將從0開始,步幅預設1。

注意:迭代器只能使用一輪次。

辦法:1)將迭代器複製乙份列表;2)通過引數來接受另外乙個函式;3)新編一種實現迭代器協議的容器類(python容器)。

*arg: 適用於能夠確定輸入的引數個數比較少時,需要把很多變數或變數名一起傳給某個函式的場合。

關鍵字引數:1)明確引數的含義; 2)在函式定義時提供預設值; 3)提供一種擴充函式引數的有效方式,使得擴充之後的函式依然能夠與原有的那些呼叫的**相相容。

注意:可選的關鍵字引數,總是應該以關鍵字形式來指定,而不是以位置引數的形式來指定。

例子:

def log(message, when=datetime.now()):

print('%s: %s' % (when, message))

log('hi there!')

sleep(0.1)

log('hi again!')

兩條訊息的時間戳是一樣的,這是因為 datetime.now() 只執行了一次,也就是它只在函式定義的時候執行了一次。引數的預設值,會在每個模組載入進來的時候求出,而很多模組都是在程式啟動時載入的。包括這段**的模組一旦載入進來,引數的預設值就固定不變了,程式不會再次執行 datetime.now()。

應該把預設值設為 none,並在文件字串裡面把 none 所對應的實際行為描述出來。

def log(message, when=none):

"""記錄時間。

args:

message:列印的訊息。

when:時間為 when 列印訊息message,預設為 present time。

"""when = datetime.now() if when is none else when

print('%s: %s' % (when, message))

以下函式引數列表裡的 * 號,標誌著位置引數就此終結,之後的那些引數,都只能以關鍵字形式來指定。

def safe_division_c(number, divisor, *, ignore_overflow=false, ignore_zero_division=false):

# ...

這樣就不能用位置引數的形式來指定關鍵字引數了,關鍵字引數不指定會採取預設值。對於接受多個布林標誌的函式,更應該這樣做。

python總結函式 Python函式之簡單總結

函式的定義 python的函式定義使用關鍵字def,如定義乙個返回絕對值的函式my abs1 5def my abs x if x 0 return x else return x 函式呼叫 引數錯誤 如果在呼叫函式時,傳給函式的引數增多或減少,python直譯器都會檢查出來 typeerror 提...

python之函式總結1

1.空函式 有的時候定義乙個函式,但不會處理什麼業務邏輯,可以這樣 def fun passpass可以看作是乙個佔位符,在if語句中也可以使用。2.引數型別檢查 python內建有乙個函式isinstance 可以對引數型別進行檢查 書寫格式 isinstance x,type x代表要進行型別檢...

python之函式總結2

1.普通引數 示例如下 def counts x print x 這個時候對函式進行呼叫,就必須有乙個對應的實參,否則就會報錯,如下 counts 5 52.含有預設值引數 示例如下 def counts x,n 3 while n 0 x x 1 n n 1 return x這時候,只需傳入對應的...