① python函數的參數類型
Python函數的參數類型主要包括必選參數、可選參數、可變參數、位置參數和關鍵字參數,本文介紹一下他們的定義以及可變數據類型參數傳遞需要注意的地方。
必選參數(Required arguments)是必須輸入的參數,比如下面的代碼,必須輸入2個參數,否則就會報錯:
其實上面例子中的參數 num1和num2也屬於關鍵字參數,比如可以通過如下方式調用:
執行結果:
可選參數(Optional arguments)可以不用傳入函數,有一個默認值,如果沒有傳入會使用默認值,不會報錯。
位置參數(positional arguments)根據其在函數定義中的位置調用,下面是pow()函數的幫助信息:
x,y,z三個參數的的順序是固定的,並且不能使用關鍵字:
輸出:
在上面的pow()函數幫助信息中可以看到位置參數後面加了一個反斜杠 / ,這是python內置函數的語法定義,Python開發人員不能在python3.8版本之前的代碼中使用此語法。但python3.0到3.7版本可以使用如下方式定義位置參數:
星號前面的參數為位置參數或者關鍵字參數,星號後面是強制關鍵字參數,具體介紹見強制關鍵字參數。
python3.8版本引入了強制位置參數(Positional-Only Parameters),也就是我們可以使用反斜杠 / 語法來定義位置參數了,可以寫成如下形式:
來看下面的例子:
python3.8運行:
不能使用關鍵字參數形式賦值了。
可變參數 (varargs argument) 就是傳入的參數個數是可變的,可以是0-n個,使用星號( * )將輸入參數自動組裝為一個元組(tuple):
執行結果:
關鍵字參數(keyword argument)允許將任意個含參數名的參數導入到python函數中,使用雙星號( ** ),在函數內部自動組裝為一個字典。
執行結果:
上面介紹的參數可以混合使用:
結果:
注意:由於傳入的參數個數不定,所以當與普通參數一同使用時,必須把帶星號的參數放在最後。
強制關鍵字參數(Keyword-Only Arguments)是python3引入的特性,可參考:https://www.python.org/dev/peps/pep-3102/。 使用一個星號隔開:
在位置參數一節介紹過星號前面的參數可以是位置參數和關鍵字參數。星號後面的參數都是強制關鍵字參數,必須以指定參數名的方式傳參,如果強制關鍵字參數沒有設置默認參數,調用函數時必須傳參。
執行結果:
也可以在可變參數後面命名關鍵字參數,這樣就不需要星號分隔符了:
執行結果:
在Python對象及內存管理機制中介紹了python中的參數傳遞屬於對象的 引用傳遞 (pass by object reference),在編寫函數的時候需要特別注意。
先來看個例子:
執行結果:
l1 和 l2指向相同的地址,由於列表可變,l1改變時,l2也跟著變了。
接著看下面的例子:
結果:
l1沒有變化!為什麼不是[1, 2, 3, 4]呢?
l = l + [4]表示創建一個「末尾加入元素 4「的新列表,並讓 l 指向這個新的對象,l1沒有進行任何操作,因此 l1 的值不變。如果要改變l1的值,需要加一個返回值:
結果:
下面的代碼執行結果又是什麼呢?
執行結果:
和第一個例子一樣,l1 和 l2指向相同的地址,所以會一起改變。這個問題怎麼解決呢?
可以使用下面的方式:
也可以使用淺拷貝或者深度拷貝,具體使用方法可參考Python對象及內存管理機制。這個問題在Python編程時需要特別注意。
本文主要介紹了python函數的幾種參數類型:必選參數、可選參數、可變參數、位置參數、強制位置參數、關鍵字參數、強制關鍵字參數,注意他們不是完全獨立的,比如必選參數、可選參數也可以是關鍵字參數,位置參數可以是必選參數或者可選參數。
另外,python中的參數傳遞屬於對象的 引用傳遞 ,在對可變數據類型進行參數傳遞時需要特別注意,如有必要,使用python的拷貝方法。
參考文檔:
--THE END--
② Python的位置參數、默認參數、關鍵字參數、可變參數區別
對於python函數參數,對於初學者可能就是進入了迷宮,盡管我也是初學者,簡單總結一下。
說參數之前,先講一下兩個packing(包裹)和unpacking(解包裹):
輸出:
我總結不了這個概念,只能幫大家到這了
一、位置參數和關鍵字參數:
調用函數時根據函數定義的參數位置來傳遞參數。
注意:
有位置參數時,位置參數必須在關鍵字參數的前面,但關鍵字參數之間不存在先後順序的
二、默認參數:
用於定義函數,為參數提供默認值,調用函數時可傳可不傳該默認參數的值(注意:所有位置參數必須出現在默認參數前,包括函數定義和調用)
三、可變參數:
定義函數時,有時候我們不確定調用的時候會傳遞多少個參數(不傳參也可以)。此時,可用包裹(packing)位置參數,或者包裹關鍵字參數,來進行參數傳遞,會顯得非常方便。
1、包裹位置傳遞
我們傳進的所有參數都會被args變數收集,它會根據傳進參數的位置合並為一個元組(tuple),args是元組類型,這就是包位置傳遞。
2、包裹關鍵字傳遞
kargs是一個字典(dict),收集所有關鍵字參數
四、解包裹參數:
*args 和 **kargs ,也可以在函數調用的時候使用,稱之為解包(unpacking)
1、在傳遞元組時,讓元組的每一個元素對應一個位置參數
2、在傳遞詞典字典時,讓詞典的每個鍵值對作為一個關鍵字參數傳遞給函數
五、位置參數、默認參數、可變參數的混合使用
1、基本原則是:先位置參數,默認參數,包裹位置,包裹關鍵字(定義和調用都應遵循)
2、Python中 *args 和 **kwargs 的區別
先看個demo:
輸出結果:
分析一下:可以看到,這兩個是[Python]中的可變參數。 *args 表示任何多個無名參數,它是一個tuple; **kwargs 表示關鍵字參數,它是一個dict。並且同時使用 *args 和 **kwargs 時,必須 *args 參數列要在 **kwargs 前,否則會報語法錯誤!!!
還有個小應用場景:創建字典
其實python中就帶有dict類,使用dict(a=1,b=2,c=3)即可創建一個字典了。
*args:
重點在*,後面的args相當於一個變數名,可以自己定義的。它的本質就是將標准調用剩下的值集中轉變為元組。
從形參的角度:
從實參的角度:
從不同角度看**kwargs:
**kwargs與位置參數和默認參數混用:
超復雜混合參數混用記:
總結:
位置參數:
調用函數時所傳參數的位置必須與定義函數時參數的位置相同
關鍵字參數:
使用關鍵字參數會指定參數值賦給哪個形參,調用時所傳參數的位置可以任意
*位置參數:可接受任意數量的位置參數(元組);只能作為最後一個位置參數出現,其後參數均為關鍵字參數
**關鍵字參數:可接受任意數量的關鍵字參數(字典);只能作為最後一個參數出現
③ python如何運行程序並向程序傳入參數
參數個數使用len()函數來獲取import sys print sys.argv if __name__=='__main__': print "Program name", sys.argv[0] for i in range(1, len(sys.argv)): print "arg%d"%i,sys.argv[i]
注意調用的時候百必須使用
python 腳本名.py arg1 arg2
因為度win下面的命令解釋器認為.py不是可執行文件,直接調用文件的內時候,不會傳入參數,容如下面的代碼則不會傳入參數:
腳本名.py arg1 arg2
④ Python語言命令行參數解析接收參數執行腳本的三種方法
在Windows系統上,Python腳本文件當然雙擊就能直接運行。不過我們往往需要在執行腳本的時候還要添加相應的參數,另外在Ubuntu系統中,我們執行文件往往和其他系統或用戶命令一樣,需要在終端中輸入,參數當然也要一並加上。所以機智客這里說的意思是,執行Python腳本(.py文件)時候需要輸入相應參數,這樣程序怎麼寫的方法。
上面這么說可能有點不明不白的,或者有朋友會用但未必知道命令行解析這種表達方式。舉個例子,比如我們在執行一個腳本文件的時候,可能會在CMD或者終端中輸入python demo.py 10或者python demo.py --separator 10後面這個數字就是參數。我們要編寫這樣的腳本或者函數,有哪些方法呢?這里列舉三種常用的。
一個是用系統模塊sys。引入模塊語句是import sys。也就是Python語言的內置庫中的sys.argv。argv通常有argv[0],argv[1],argv[2]這樣幾個參數。基本使用方法是m_sil_len = int(sys.argv[1])傳入第一個參數,sil_th = int(sys.argv[2])傳入第二個參數。如果是簡單一點的參數或者腳本,我們引入了sys。可以直接用這個傳入參數。
一種是用模塊argparse來實現,這是標准庫中推薦的命令行解析模塊。引入模塊語句是import argparse。基本使用方法是引入模塊後,先parser = argparse.ArgumentParser()創建對象,然後調用方法添加參數parser.add_argument("jzk", help="這是關於參數的說明", type=int),之後args = parser.parse_args()使用解析就可以用了。機智客看到這個方法在很多項目腳本中使用。我們在閱讀機器學習AI之類的開源項目,就會發現很多人用的都是這個方法。
還有一個就是用fire模塊,用於生成命令行界面的工具。引入模塊語言是import fire。它默認以-為參數分隔符的。基本使用方法是fire.Fire()。這個不僅可以做命令行的參數解析,還可以還給一個類class添加命令行。所以使用時候括弧里填入函數名或者類名即可,也就是裡面的參數可以是其他Python對象。
⑤ Python筆記:命令行參數解析
有些時候我們需要通過命令行將參數傳遞給腳本,C語言中有個getopt()方法,python中也有個類似的命令行參數解析方法getopt()。python也提供了比getopt()更簡潔的argparse方法。另外,sys模塊也可以實現簡單的參數解析,本文將對這3種命令行參數解析方法簡要介紹。
sys.argv是傳入的參數列表,sys.argv[0]是當前python腳本的名稱,sys.argv[1]表示第一個參數,以此類推。
命令行運行:
可以看到傳入的參數通過sys.argv來獲取,它就是一個參數列表。
python的getopt與C語言的的getopt()函數類似。相比於sys模塊,支持長參數和短參數,並對參數解析賦值。但它需要結合sys模塊進行參數解析,語法格式如下:
短參數為單個英文字母,如果必須賦值需要在後面加英文冒號( : ),長參數一般為字元串(相比短參數,更能說明參數含義),如果必須賦值需要在後面加等號( = )。
命令行運行:
注意:短參數(options)和長參數(long_options)不需要一一對應,可以任意順序,也可以只有短參數或者只有長參數。
argparse模塊提供了很多可以設置的參數,例如參數的默認值,幫助消息,參數的數據類型等。argparse類主要包括ArgumentParser、add_argument和parse_args三個方法。
下面介紹這三個函數的使用方法。
argparse默認提供了 -h | --help 參數:
命令行運行:
下面列出部分參數:
下面來添加參數:
命令行運行:
parse_args() 方法用於解析參數,在前面的示例代碼中使用parse_args方法來提取參數值,對於無效或者錯誤的參數會列印錯誤信息和幫助信息:
命令行運行:
本文介紹了Python的三種命令行參數解析方法sys.argv、getopt和argparse,可以根據自己的需要進行選擇,getopt和argparse兩種方法相比來說,建議選擇argparse,代碼量更少更簡潔。更詳細的使用方法參考官方文檔:
--THE END--
⑥ Python參數類型
上一期我們學習參數傳遞怎麼傳遞,也了解了參數的幾種類型。
首先,我們再來回顧一下,形參和實參:
形參是在定義函數時定義的,放在函數名後面的圓括弧里,可為空
實參是調用函數時為形參傳入具體的參數值
簡單總結一下,誰調用函數,誰就負責傳入參數。
好吶,本期我們來詳細學習函數幾種參數類型,大綱如下:
python函數的參數名是無意義的,Python允許在調用函數時通過通過名字來傳入參數值。
位置參數:按照形參位置傳入的參數
調用函數時,實參默認按位置順序傳遞的。同時實參個數也要和形參匹配
舉一個小栗子
如果實參的個數與形參不匹配時,調用函數運行就會報錯
Python中,形參與調用函數緊密聯系在一起的。
關鍵字參數:調用函數時,使形參名稱來傳遞參數,形式為「形參名=實參」
關鍵字參數,又叫命名參數,傳遞時無需考慮參數位置和順序
舉一個小栗子
默認參數:定義函數時,我們可以為形參提前設置具體的值。
在定義函數時,默認參數要放到位置等其他參數後面
在調用函數時,默認參數是可選的。如果傳入新值,則會覆蓋默認值
舉一個小栗子
注意,默認值不能位於位置參數前面,否則程序會報錯誤
不定長參數又名可變參數。
不定長參數指的是可變數量的參數,分兩種情況:
如果不定長參數後面,可以新增參數嗎?
我們通過例子來看,會發生什麼?
運行上面的程序,Python解釋器會報錯
原因是,形參a已經是不定長參數,我們調用的test(2,3,4)傳入的三個實參,系統自動把它們屬於形參a的值,形參b 和形參c就等於沒有值傳入,這時候系統就認為,調用函數的對象,參數沒有傳夠。
為了解決這一報錯,python引入了 強制命名參數
規定,調用不定參數後面有跟位置參數的函數時,傳入給位置參數時,必須要強制命名參進行傳參。
逆向參數收集針對的對象傳入函數的實參
調用函數時,如果實參是元組,列表或者字典,通過在實參前面加入星號,可以自動把元素進行隔開,然後再轉入給函數進行處理
舉一個小栗子
本期,我們詳細學習了參數幾種類型,為後面我們學習函數,打好基礎。
實踐是檢驗真理的過程,大家多動手練習練習,會有不一樣的奇妙旅程~
好吶,以上是本期內容,歡迎大佬們評論區指正~
⑦ Python基礎之pytest參數化
pytest是目前比較成熟功能齊全的測試框架,使用率肯定也不斷攀升。在實際
工作中,許多測試用例都是類似的重復,一個個寫最後代碼會顯得很冗餘。這里,我們來了解一下
@pytest.mark.parametrize裝飾器,可以很好的解決上述問題。
釋義:參數名稱
格式:字元串"arg1,arg2,arg3"
釋義:參數值列表
格式:必須是列表,如[val1,val2,val3]
單個參數,裡面是值的列表,如@pytest.mark.parametrize("name",["Jack","Locus","Bill"])
多個參數,需要用元祖來存放值,一個元祖對應一組參數的值,如@pytest.mark.parametrize("user,age",[("user1",15),("user2",24),("user3",25)])
釋義:可以理解為用例的id
格式:字元串列表,如["case1","case2","case3"]
釋義:當indirect=True時,若傳入的argnames是fixture函數名,此時fixture函數名將成為一個可執行的函數,
argvalues作為fixture的參數,執行fixture函數,最終結果再存入 request.param;當indirect=False時,fixture
函數只作為一個參數名給測試收集階段調用。
備註:這里可以將the setup phase(測試設置階段)理解為配置 conftest.py 階段,將the collection phase(
測試收集階段)理解為用例執行階段。
由以上代碼可以看到,當裝飾器裝飾測試類時,定義的數據集合會被傳遞給類的所有方法。
當測試用例只需要一個參數時,我們存放數據的列表無序嵌套序列,@pytest.mark.parametrize("name", data)
裝飾器的第一個參數也只需要一個變數接收列表中的每個元素,第二個參數傳遞存儲數據的列表,那麼測試用
例需要使用同名的字元串接收測試數據(實例中的name)且列表有多少個元素就會生成並執行多少個測試用例。
當測試用例需要多個數據時,我們可以使用嵌套序列(嵌套元組&嵌套列表)的列表來存放測試數據。
裝飾器@pytest.mark.parametrize()可以使用單個變數接收數據,也可以使用多個變數接收,同樣,測
試用例函數也需要與其保持一致。
當使用單個變數接收時,測試數據傳遞到測試函數內部時為列表中的每一個元素或者小列表,需
要使用索引的方式取得每個數據。
當使用多個變數接收數據時,那麼每個變數分別接收小列表或元組中的每個元素列表嵌套多少個多
組小列表或元組,測生成多少條測試用例。
通過測試結果,我們不難分析,一個測試函數還可以同時被多個參數化裝飾器裝飾,那麼多個
裝飾器中的數據會進行交叉組合的方式傳遞給測試函數,進而生成n * n個測試用例。
輸出結果顯示收集到4個用例,兩個通過,一個被跳過,一個標記失敗,當我們不想執行某組測試
數據時,我們可以標記skip或skipif;當我們預期某組數據會執行失敗時,我們可以標記為xfail等。
參數化裝飾器有一個額外的參數ids,可以標識每一個測試用例,自定義測試數據結果的顯示,
為了增加可讀性,我們可以標記每一個測試用例使用的測試數據是什麼,適當的增加一些說明。
在使用前你需要知道,ids參數應該是一個字元串列表,必須和數據對象列表的長度保持一致。
不加ids參數的返回結果
加ids參數的返回結果
我們可以看到帶ids參數的返回結果中的用例都被一個列表明確的標記了,而且通過這種標記
可以更加直觀的看出來,每個測試用例使用的數據名稱及測試內容。