1. 程式人生 > >Python一一引數

Python一一引數

引數

傳遞引數

(1).引數的傳遞是通過自動將物件賦值給本地變數名來實現的。所有的引數實際上都是通過指標進行傳遞的。作為引數被傳遞的物件從來不自動拷貝。

(2).在函式內部的引數名的賦值不會影響呼叫者

(3).改變函式的可變物件引數的值也許會對呼叫者有影響。因為引數是簡單地賦值給傳入的物件,函式能夠就地改變傳入的可變物件。因此其結果會影響呼叫者。可變引數對於函式來說是可以做輸入和輸出的。

Python的通過賦值進行傳遞的機制與C++的引用引數選項並不完全相同,但是在實際中,它與C語言的引數傳遞模型相當相似。

(1).不可變引數“通過值”進行傳遞。像整數和字串這樣的物件是通過物件引用而不是拷貝進行傳遞的,但是因為你無論怎樣都不可能在原處改變不可變物件,實際效果就很像建立了一份拷貝。

(2).可變物件是通過“指標”進行傳遞的。例如,列表和字典這樣的物件也是通過物件引用進行傳遞的,這一點與C語言使用指標傳遞陣列很相似:可變物件能夠在函式內部進行原處改變,這一點與C陣列很像。

引數和共享引用

因為a是在函式作用域內的本地變數名,第一個賦值對函式呼叫者沒有影響,它僅僅把本地變數a修改為引用一個完全不同的物件,並沒有改變呼叫者作用域中的名稱X的繫結。

b也是一個本地變數名,但是它被傳給一個可變物件,因為第二個賦值是一個在原處發生的物件改變,對函式中b[0]進行賦值的結果會在函式返回後影響L的值。

避免可變引數的修改

如果不想要函式內部在原處的修改影響傳遞給它的物件,那麼,我們可以簡單地建立一個明確的可變物件的拷貝。

如果不想改變傳入的物件,我們可以在函式內部進行拷貝:

為了真正意義上防止這些改變,我們總是能夠將可變物件轉換為不可變物件來杜絕這種問題,例如,將其轉換為元組(不可變屬性),這樣在試圖改變時,會觸發異常:

如果在你沒有預期的情況下物件在外部發生了改變,檢查一下是不是一個呼叫了的函式引起的,並且有必要的話當傳入物件時進行拷貝。

對引數輸出進行模擬

返回一個包含兩個元素的元組,它的括號是可選的,這裡省略了。

特定的引數匹配模型

基礎知識

關於引數匹配模型的一些大綱:

(1).位置從左至右進行匹配

(2).關鍵字引數:通過引數名進行匹配(使用name = value語法)

(3).預設引數:為沒有傳入值的引數定義引數值(使用name = value語法)

(4).可變引數:收集任意多基於位置或關鍵字的引數(以字元*開頭,收集任意多的額外引數)

(5).可變引數解包:傳遞任意多的基於位置或關鍵字的引數(呼叫者能夠再使用*語法去將引數集合打散,分成引數。這個*與在函式頭部的*恰恰相反:在函式頭部意味著收集任意多的引數,而在呼叫者中意味著傳遞任意多的引數。)

(6).Keyword-only引數:引數必須按照名稱傳遞(在Python3.0中,函式也可以指定引數,引數必須用帶有關鍵引數的名字(而不是位置)來傳遞。)

匹配語法

細節

Python遵從下面法則:

(1).在函式呼叫中,引數必須以此順序出現:任何位置引數(value),後面跟著任何關鍵字引數(name=value)和*sequence形式的組合,後面跟著**dict形式

(2).在函式頭部,引數必須以此順序出現:任何一般引數(name),緊跟著任何預設引數(name=value),如果有的話,後面是*name(或者在Python3.0中是*)的形式,後面跟著任何name或name=value keyword-only引數(在Python3.0中),後面跟著**name形式。

Python內部是使用以下的步驟來在賦值前進行引數匹配的:

(1).通過位置分配非關鍵字引數

(2).通過匹配變數名分配關鍵字引數

(3).其他額外的非關鍵字引數分配到*name元組中

(4).其他額外的關鍵字引數分配到**name字典中

(5).用預設值分配給在頭部未得到分配的引數

關鍵字引數和預設引數的例項

首先我們看通過位置從左至右匹配變數名

關鍵字引數

關鍵字引數允許通過變數名

預設引數

關於函式頭部和函式呼叫中特定的name=value語法:

在函式頭部:為一個可選的引數定義預設值

在函式呼叫:通過變數名進行匹配的關鍵字

這兩種情況都不是一個賦值語句,它是在這兩種情況下的特定語法,改變了預設的引數匹配機制。

關鍵字引數和預設引數的混合

任意引數的例項(*和**)

收集引數(函式定義中使用*)

第一種用法:在元組中收集不匹配的位置引數

第二種用法:**允許將關鍵字引數轉換為字典,你能夠在之後使用鍵呼叫進行步進或字典迭代

第三種:混合用法

解包引數(函式呼叫中使用*)

Python3.0 Keyword-Only引數

keyword-only引數一一即必須只按照關鍵字傳遞並且不會由一個位置引數來填充的引數。如果想要一個函式既處理任意多個引數,也接受可能的配置選項的話,這是很有用的。

語法:keyword-only引數編碼為命名的引數,出現在引數列表中的*args之後。所有這些引數都必須在呼叫中使用關鍵字語法來傳遞

排序規則

注意:keyword-only引數必須在一個星號後面指定,而不是兩個星號一一命名的引數不能出現在**args任意關鍵字形式的後面,而且一個**不能獨自出現在引數列表中,這兩種做法都將產生語法錯誤:

上述規則意味著:

在一個函式頭部:keyword-only引數必須編寫在**args任意關鍵字形式之前,且在*args任意位置形式之後。

在函式呼叫中:當傳遞keyword-only引數時,它們必須出現在一個**args形式之前。keyword-only引數可以編寫在*args之前或者之後,並且可能包含在**args中: