Python關鍵字及可變參數*args,**kw原理解析_python

來源:腳本之家  責任編輯:小易  

   這篇文章主要介紹了Python中的默認參數詳解,本文講解了默認參數的基本原理、如何正確地使用可變參數等內容,需要的朋友可以參考下   文章的主題   不要使用可變對象作為函數的默認參數例如 list,dict,因為def是一個可執行語句,只有def執行的時候才會計算默認默認參數的值,所以使用默認參數會造成函數執行的時候一直在使用同一個對象,引起bug。   基本原理   在 Python 源碼中,我們使用def來定義函數或者方法。在其他語言中,類似的東西往往只是一一個語法聲明關鍵字,但def卻是一個可執行的指令。Python代碼執行的時候先會使用 compile 將其編譯成 PyCodeObject.   PyCodeObject 本質上依然是一種靜態源代碼,只不過以字節碼方式存儲,因為它面向虛擬機。因此 Code 關注的是如何執行這些字節碼,比如棧空間大小,各種常量變量符號列表,以及字節碼與源碼行號的對應關系等等。   PyFunctionObject 是運行期產生的。它提供一個動態環境,讓 PyCodeObject 與運行環境關聯起來。同時為函數調用提供一系列的上下文屬性,諸如所在模塊、全局名字空間、參數默認值等等。這是def語句執行的時候干的活。   PyFunctionObject 讓函數面向邏輯,而不僅僅是虛擬機。PyFunctionObject 和 PyCodeObject 組合起來才是一個完整的函數。   下文翻譯了一篇文章,有一些很好的例子。但是由于水平有限,有些不會翻譯或者有些翻譯有誤,敬請諒解。如果有任何問題請發郵件到 acmerfight圈gmail.com,感激不盡   主要參考資料 書籍:《深入Python編程》 大牛:shell 和 Topsky   Python對于函數中默認參數的處理往往會給新手造成困擾(但是通常只有一次)。   當你使用“可變”的對象作為函數中作為默認參數時會往往引起問題。因為在這種情況下參數可以在不創建新對象的情況下進行修改,例如 list dict。    代碼如下:   >>> def function(data=[]):   ... data.append(1)   ... return data   ...   >>> function()   [1]   >>> function()   [1, 1]   >>> function()   [1, 1, 1]   像你所看到的那樣,list變得越來越長。如果你仔細地查看這個list。你會發現list一直是同一個對象。    代碼如下:   >>> id(function())   12516768   >>> id(function())   12516768   >>> id(function())   12516768   原因很簡單: 在每次函數調用的時候,函數一直再使用同一個list對象。這么使用引起的變化,非常“sticky”。   為什么會發生這種情況?   當且僅當默認參數所在的“def”語句執行的時候,默認參數才會進行計算。請看文檔描述   https://docs.python.org/2/reference/compound_stmts.html#function-definitions   其中有下面一段   "Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function,e.g.:    代碼如下:   def whats_on_the_telly(penguin=None):   if penguin is None:   penguin = []   penguin.append("property of the zoo")   return penguin   "   "def"是Python中的可執行語句,默認參數在"def"的語句環境里被計算。如果你執行了"def"語句多次,每次它都將會創建一個新的函數對象。接下來我們將看到例子。   用什么來代替?   像其他人所提到的那樣,用一個占位符來替代可以修改的默認值。None    代碼如下:   def myfunc(value=None):   if value is None:   value = []   # modify value here   如果你想要處理任意類型的對象,可以使用sentinel    代碼如下:   sentinel = object()   def myfunc(value=sentinel):   if value is sentinel:   value = expression   # use/modify value here   在比較老的代碼中,written before “object” was introduced,你有時會看到    代碼如下:   sentinel = ['placeholder']   譯者注:太水,真的不知道怎么翻譯了。我說下我的理解 有時邏輯上可能需要傳遞一個None,而你的默認值可能又不是None,而且還剛好是個列表,列表不   可以寫在默認值位置,所以你需要占位符,但是用None,你又不知道是不是調用者傳遞過來的那個   正確地使用可變參數   最后需要注意的是一些高深的Python代碼經常會利用這個機制的優勢;舉個例子,如果在一個循環里創建一些UI上的按鈕,你可能會嘗試這樣去做:    代碼如下:   for i in range(10):   def callback():   print "clicked button", i   UI.Button("button %s" % i, callback)   但是你卻發現callback打印出相同的數字(在這個情況下很可能是9)。原因是Python的嵌套作用域只是綁定變量,而不是綁定數值的,所以callback只看到了變量i綁定的最后一個數值。為了避免這種情況,使用顯示綁定。    代碼如下:   for i in range(10):   def callback(i=i):   print "clicked button", i   UI.Button("button %s" % i, callback)   i=i把callback的參數i(一個局部變量)綁定到了當前外部的i變量的數值上。(譯者注:如果不理解這個例子,請看http://stackoverflow.com/questions/233673/lexical-closures-in-python)   另外的兩個用途local caches/memoization    代碼如下:   def calculate(a, b, c, memo={}):   try:   value = memo[a, b, c] # return already calculated value   except KeyError:   value = heavy_calculation(a, b, c)   memo[a, b, c] = value # update the memo dictionary   return value   (對一些遞歸算法非常好用)   對高度優化的代碼而言, 會使用局部變量綁全局的變量:    代碼如下:   import math   def this_one_must_be_fast(x, sin=math.sin, cos=math.cos):   ...   這是如何工作的?   當Python執行一條def語句時, 它會使用已經準備好的東西(包括函數的代碼對象和函數的上下文屬性),創建了一個新的函數對象。同時,計算了函數的默認參數值。   不同的組件像函數對象的屬性一樣可以使用。上文用到的'function'    代碼如下:   >>> function.func_name   'function'   >>> function.func_code   ", line 1>   >>> function.func_defaults   ([1, 1, 1],)   >>> function.func_globals   {'function': ,   '__builtins__': ,   '__name__': '__main__', '__doc__': None}   這樣你可以訪問默認參數,你甚至可以修改它。    代碼如下:   >>> function.func_defaults[0][:] = []   >>> function()   [1]   >>> function.func_defaults   ([1],)   然而我不推薦你平時這么使用。   另一個重置默認參數的方法是重新執行相同的def語句,Python將會和代碼對象創建一個新的函數對象,并計算默認參數,并且把新創建的函數對象賦值給了和上次相同的變量。但是再次強調,只有你清晰地知道在做什么的情況下你才能這么做。   And yes, if you happen to have the pieces but not the function, you can use the function class in the new module to create your own function objectwww.13333515.buzz防采集請勿采集本網。

可變參數

顧名思義,函數的可變參數是傳入的參數可以變化的,1個,2個到任意個。當然可以將這些 參數封裝成一個 list 或者 tuple 傳入,但不夠 pythonic。使用可變參數可以很好解決該問題,注意可變參數在函數定義不能出現在特定參數和默認參數前面,因為可變參數會吞噬掉這些參數。

這是Python函數可變參數 args及kwargs *args表示任何多個無名參數,它是一個tuple**kwargs表示關鍵字參數,它是一個dict 測試代碼如下:123456789def foo(*args,**kwarg

在用除法操作時,第二個參數為0時引發了該錯誤 ValueError:值錯誤,傳給對象的參數類 嘗試使用Python關鍵字作為變量名(導致“SyntaxError:invalid syntax”) Python關鍵不能

def report(name, *grades): total_grade = 0 for grade in grades: total_grade += grade print(name, 'total grade is ', total_grade)

Python 3.x中新加入了一個關鍵字 nonlocal 以支持修改綁定變量。但不管支持程度如何 函數式編程語言一般會提供數據結構的兩種版本(可變和不可變),并推薦使用不可變的版

定義了一個函數,傳入一個參數為 name, 后面的參數*grades 使用了 * 修飾,表明該參數是一個可變參數,這是一個可迭代的對象。該函數輸入姓名和各科的成績,輸出姓名和總共成績。所以可以這樣調用函數 report('Mike', 8, 9),輸出的結果為 Mike total grade is 17, 也可以這樣調用 report('Mike', 8, 9, 10),輸出的結果為 Mike total grade is 27

函數定義 def fuc_name(arg): [return ] 函數參數 普通參數fuc_name(arg) 默認參數fuc_name(arg=default) 可變參數fuc_name(*arg) (結合tuple) 關鍵字參數fuc_name(*

關鍵字參數

關鍵字參數可以傳入0個或者任意個含參數名的參數,這些參數名在函數定義中并沒有出現,這些參數在函數內部自動封裝成一個字典(dict).

12)嘗試使用Python關鍵字作為變量名(導致“SyntaxError:invalid syntax”) Python關鍵不 也許這才是你想做的: spam = 1 spam += 1 17)忘記為方法的第一個參數添加self參數(導

在用除法操作時,第二個參數為0時引發了該錯誤 ValueError:值錯誤,傳給對象的參數類 嘗試使用Python關鍵字作為變量名(導致“SyntaxError:invalid syntax”) Python關鍵不能

def portrait(name, **kw): print('name is', name) for k,v in kw.items(): print(k, v)

嘗試使用Python關鍵字作為變量名(導致“SyntaxError:invalid syntax”) Python關鍵不能 spam = 1 spam += 1 17)忘記為方法的第一個參數添加self參數(導致“TypeError: my

定義了一個函數,傳入一個參數 name, 和關鍵字參數 kw,使用了 ** 修飾。表明該參數是關鍵字參數,通常來講關鍵字參數是放在函數參數列表的最后。如果調用參數 portrait('Mike', age=24, country='China', education='bachelor') 輸出:

Python常見數據結構整理 Python中常見的數據結構可以統稱為容器(container)。序列( str1=str1.substitute(x='100') print str1 輸出:100$ 除了關鍵字參數之外,模板字符串還可

val except StopIteration: pass 實際上,因為迭代操作如此普遍,Python專門將關鍵字for用 如果不指定n,則無限重復。 repeat(10, 3) --> 10 10 10 3.4.2. 在最短的序列參數終止時

name is Mike

這將產生以下結果: ? 1 Hello, Python! 腳本模式編程: 調用解釋器及腳本作為參數,并開始 所有Python關鍵字只包含小寫字母。 行和縮進: 一個程序員學習Python時,遇到的第一個

age 24

想知道它干了什么而已。 一句一句翻譯沒什么意義,告訴你幾個方法和關鍵字的含義,你 但是元祖本身是不可變的。 def xxx 定義函數,類似javascript中的 function xxx() python中

country China

Python的函數定義非常簡單,但靈活度卻非常大。除了正常定義的必選參數外,還可以使用默認參數、可變參數和關鍵字參數,使得函數定義出來的接口,不但能處理復雜的參數,還

education bachelor

通過可變參數和關鍵字參數,任何函數都可以用 universal_func(*args, **kw) 表達。

剛學用Python的時候,特別是看一些庫的源碼時,經常會看到func(*args, **kwargs)這樣的函數定義,這個*和**讓人有點費解。其實只要把函數參數定義搞清楚了,就不難理解了。先說說函數定義,我們都知道,下面的代碼定義了一個函數funcAdef funcA():pass顯然,函數funcA沒有參數(同時啥也不干:D)。下面這個函數funcB就有兩個參數了,def funcB(a, b):print aprint b調用的時候,我們需要使用函數名,加上圓括號擴起來的參數列表,比如 funcB(100, 99),執行結果是:10099很明顯,參數的順序和個數要和函數定義中一致,如果執行funcB(100),Python會報錯的:TypeError: funcB() takes exactly 2 arguments (1 given)我們可以在函數定義中使用參數默認值,比如def funcC(a, b=0):print aprint b在函數funcC的定義中,參數b有默認值,是一個可選參數,如果我們調用funcC(100),b會自動賦值為0。OK,目前為止,我們要定義一個函數的時候,必須要預先定義這個函數需要多少個參數(或者說可以接受多少個參數)。一般情況下這是沒問題的,但是也有在定義函數的時候,不能知道參數個數的情況(想一想C語言里的printf函數),在Python里,帶*的參數就是用來接受可變數量參數的。看一個例子def funcD(a, b, *c):print aprint bprint "length of c is: %d " % len(c)print c調用funcD(1, 2, 3, 4, 5, 6)結果是12length of c is: 4(3, 4, 5, 6)我們看到,前面兩個參數被a、b接受了,剩下的4個參數,全部被c接受了,c在這里是一個tuple。我們在調用funcD的時候,至少要傳遞2個參數,2個以上的參數,都放到c里了,如果只有兩個參數,那么c就是一個empty tuple。好了,一顆星我們弄清楚了,下面輪到兩顆星。上面的例子里,調用函數的時候,傳遞的參數都是根據位置來跟函數定義里的參數表匹配的,比如funcB(100, 99)和funcB(99, 100)的執行結果是不一樣的。在Python里,還支持一種用關鍵字參數(keyword argument)調用函數的辦法,也就是在調用函數的時候,明確指定參數值付給那個形參。比如還是上面的funcB(a, b),我們通過這兩種方式調用funcB(a=100, b=99)和funcB(b=99, a=100)結果跟funcB(100, 99)都是一樣的,因為我們在使用關鍵字參數調用的時候,指定了把100賦值給a,99賦值給b。也就是說,關鍵字參數可以讓我們在調用函數的時候打亂參數傳遞的順序!另外,在函數調用中,可以混合使用基于位置匹配的參數和關鍵字參數,前題是先給出固定位置的參數,比如def funcE(a, b, c):print aprint bprint c調用funcE(100, 99, 98)和調用funcE(100, c=98, b=99)的結果是一樣的。好了,經過以上鋪墊,兩顆星總算可以出場了:如果一個函數定義中的最后一個形參有 ** (雙星號)前綴,所有正常形參之外的其他的關鍵字參數都將被放置在一個字典中傳遞給函數,比如:def funcF(a, **b):print afor x in b:print x + ": " + str(b[x])調用funcF(100, c='你好', b=200),執行結果100c: 你好b: 200大家可以看到,b是一個dict對象實例,它接受了關鍵字參數b和c內容來自www.13333515.buzz請勿采集。


  • 本文相關:
  • python *args和**kwargs用法實例解析
  • python中*args和**kwargs的區別詳解
  • 對python中的*args與**kwgs的含義與作用詳解
  • python可變參數*args和**kwargs用法實例小結
  • python函數中*args和**kwargs來傳遞變長參數的用法
  • python函數參數*args**kwargs用法實例
  • 用實例說明python的*args和**kwargs用法
  • python pandas 如何替換某列的一個值
  • 深入淺析python變量加逗號,的含義
  • python把數組中的數字每行打印3個并保存在文檔中的方法
  • 淺析django中關于session的使用
  • python讀取json數據操作實例解析
  • python計算三維矢量幅度的方法
  • python json.loads兼容單引號數據的方法
  • python 通過requests實現騰訊新聞抓取爬蟲的方法
  • python2 與python3的版本區別實例分析
  • django給admin添加action的步驟詳解
  • python 函數變量 參數怎么使用
  • Python中的默認參數詳解
  • Python中函數的參數傳遞與可變長參數介紹
  • 請問這個python腳本哪里出錯了?打印出一個無限循環的數
  • Python代碼中func(*args, **kwargs)是什么意思
  • Python 運行報錯NameError出現原因,怎么解決
  • Python函數式編程指南(一):函數式編程概述
  • python 的script怎么用
  • python 出現這個錯誤是什么原因
  • python 出現這個錯誤是什么原因
  • python 出現這個錯誤是什么原因
  • 有哪些用 Python 語言講算法和數據結構的書
  • Python函數式編程指南(三):迭代器詳解
  • Python編程入門的一些基本知識
  • python新手, 求幫忙翻譯一段代碼
  • 定義函數的參數時,用IDataParameter[]和SqlParameter[]有何區...
  • 為什么 Kotlin 是我下一門要使用的語言
  • 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全vbsdos/bathtahtcpythonperl游戲相關vba遠程腳本coldfusionruby專題autoitseraphzonepowershelllinux shellluagolangerlang其它首頁python *args和**kwargs用法實例解析python中*args和**kwargs的區別詳解對python中的*args與**kwgs的含義與作用詳解python可變參數*args和**kwargs用法實例小結python函數中*args和**kwargs來傳遞變長參數的用法python函數參數*args**kwargs用法實例用實例說明python的*args和**kwargs用法python pandas 如何替換某列的一個值深入淺析python變量加逗號,的含義python把數組中的數字每行打印3個并保存在文檔中的方法淺析django中關于session的使用python讀取json數據操作實例解析python計算三維矢量幅度的方法python json.loads兼容單引號數據的方法python 通過requests實現騰訊新聞抓取爬蟲的方法python2 與python3的版本區別實例分析django給admin添加action的步驟詳解python入門教程 超詳細1小時學會python 列表(list)操作方法詳解python 元組(tuple)操作詳解python 字典(dictionary)操作詳解pycharm 使用心得(一)安裝和首python strip()函數 介紹python 中文亂碼問題深入分析python中使用xlrd、xlwt操作excepython科學計算環境推薦——anacpython逐行讀取文件內容的三種方python flask 裝飾器順序問題解決多個應用共存的django配置方法python處理excel xlrd的簡單使用python中單下劃線_的常見用法總結linux下使用python調用top命令獲得cpu利用詳解python讀取yaml文件多層菜單pandas中dataframe的分組/分割/合并的實現numpy ndarray 按條件篩選數組,關聯篩選的在python中使用pil模塊處理圖像的教程windows下ipython的安裝與使用詳解
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.13333515.buzz All Rights Reserved
    3排列五开奖结果