1. 程式人生 > >Python的坑(7) -- 定義預設引數要牢記一點:預設引數必須指向不變物件!

Python的坑(7) -- 定義預設引數要牢記一點:預設引數必須指向不變物件!

原文連結:

http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000

預設引數很有用,但使用不當,也會掉坑裡。預設引數有個最大的坑,演示如下:

先定義一個函式,傳入一個list,新增一個END再返回:

def add_end(L=[]):
    L.append('END')
    return L

當你正常呼叫時,結果似乎不錯:

>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z']) ['x', 'y', 'z', 'END']

當你使用預設引數呼叫時,一開始結果也是對的:

>>> add_end()
['END']

但是,再次呼叫add_end()時,結果就不對了:

>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

很多初學者很疑惑,預設引數是[],但是函式似乎每次都“記住了”上次添加了'END'後的list。

原因解釋如下:

Python函式在定義的時候,預設引數L

的值就被計算出來了,即[],因為預設引數L也是一個變數,它指向物件[],每次呼叫該函式,如果改變了L的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的[]了。

所以,定義預設引數要牢記一點:預設引數必須指向不變物件!

要修改上面的例子,我們可以用None這個不變物件來實現:

def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L

現在,無論呼叫多少次,都不會有問題:

>>> add_end()
['END']
>>> add_end
() ['END']

為什麼要設計strNone這樣的不變物件呢?因為不變物件一旦建立,物件內部的資料就不能修改,這樣就減少了由於修改資料導致的錯誤。此外,由於物件不變,多工環境下同時讀取物件不需要加鎖,同時讀一點問題都沒有。我們在編寫程式時,如果可以設計一個不變物件,那就儘量設計成不變物件。


相關推薦

Python7 -- 定義預設引數牢記一點預設引數必須指向物件

原文連結: http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb90

Python之——預設引數必須指向物件

先定義一個函式,傳入一個list,新增一個END再返回: def add_end(L=[]): L.append('END') return L 當你正常呼叫時,結果似乎不錯: >>> add_end([1,

機器學習 Python scikit-learn 中文文件7模型選擇: 選擇合適的估計器及其引數

模型選擇: 選擇合適的估計器及其引數 與官方文件完美匹配的中文文件,請訪問 https://www.studyai.cn Score, 和 cross-validated scores 交叉驗證生成器 網格搜尋與交叉驗證估計器 網格搜尋 自帶交叉驗證的估計器 模型選擇: 選擇

python手記7------字典操作方法

file desc number getitem 空數組 present 返回字典 hash out 1.dict方法概述 In[70]: dir(dict) Out[69]: [‘__class__‘, ‘__contains__‘, ‘__delattr__‘

python基礎7元祖類型賦值補充

pre 定義 index orm python 報錯 {} 兩個 子字符串 前面學了列表和字典,今天我們看一個和列表相似的類型元祖。 預習: 簡單購物車   實現打印商品詳細信息,用戶輸入商品名和購買個數,則將商品名,價格,購買個數加入購物列表,如果輸入為空或其他非法輸入則

Python基礎7基本數據類型dict

sel open name sta allow zed items 格式 鍵值對 字典(dict):   說明:字典是另一種可變容器模型,且可存儲任意類型對象。字典的每個鍵值(key=>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號{

Python基礎7函式

函式:被組織好的,可重複使用的,用來實現單一功能或相關聯功能的程式碼塊。 合理利用函式,可以增強應用的模組性,提高程式碼的重複使用率。 比如常用的求絕對值,最大值,字串長度等這些模組,都已經被封裝成內建函式abs(),max(),len()。 當然有一些只對於你個人的專案而言常用的模組,在找不

Python學習7——面向物件高階編輯

1、使用__slots__ (1)可以嘗試給例項繫結一個方法: def set_age(self, age): self.age = age from types import MethodType s.set_age = MethodType(set_age, s) # 給例項

吳裕雄 實戰PYTHON程式設計7

import os from win32com import client word = client.gencache.EnsureDispatch('Word.Application')word.Visible = 1word.DisplayAlerts = 0doc = word.Documents

機器學習 第一章 Python複習7urllib

1.urllib 參考文件 urlopen如果是HTTP和HTTPS URL,則會返回一個http.client.HTTPResponse物件 參考文件 from urllib.request import urlopen response = ur

python學習7python爬蟲之爬取動態載入的圖片,以百度圖片為例

前言: 前面我們爬取圖片的網站都是靜態的,在頁面中右鍵檢視原始碼就能看到網頁中圖片的位置。這樣我們用requests庫得到頁面原始碼後,再用bs4庫解析標籤即可儲存圖片到本地。 當我們在看百度圖片時,右鍵–檢查–Elements,點選箭頭,再用箭頭點選圖片時

Python基礎7——名片管理系統實現了資料簡單的儲存、修改、刪除、檢視等

進行了一些Python基礎知識的學習後,將這些知識進行綜合,實現了名片管理小系統,可以進行資料的增刪改查。 主要思路是將名片(資訊)存進字典裡,再將字典存入列表裡,方便進行增刪改查。 程式碼如下: #-*-encoding:utf-8-*- #用來儲存名片 card_in

小白學 Python 爬蟲7HTTP 基礎

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

【程式設計師眼中的統計學7】正態分佈的運用正態之美

作者 白寧超 2015年10月15日18:30:07 摘要:程式設計師眼中的統計學系列是作者和團隊共同學習筆記的整理。首先提到統計學,很多人認為是經濟學或者數學的專利,與計算機並沒有交集。誠然在傳統學科中,其在以上學科發揮作用很大。然而隨著科學技術的發展和機器智慧的普及,統計學在機器智慧中的作用越來

Spring第一課基於XML裝配bean,三種例項化方式預設構造、靜態工廠、例項工廠

Spring中基於XML中的裝配bean有三種方式: 1.預設構造 2.靜態工廠 3.例項工廠 1.預設構造     在我們在Spring的xml檔案中直接通過:     <bean id="名字" class="全限定類名" ></bea

筆記Python 默認參數必須指向對象

end 解決 必須 筆記 參數 none turn return def 筆記:Python 默認參數必須指向不變對象 學習記錄 >>> def add_end(L=[]): L.append('END') return

洗禮靈魂,修煉python7--元組,集合,可變集合

服務器 .cn mov src 核心 是什麽 報錯 move 之前 前面已經把列表的基本用法講解完 接著講python的幾大核心之——元組(tuple) 1.什麽是元組? 類似列表,但為不可變對象,之前提到列表是可變對象,所謂可變對象就是支持原處修改,並且在修改前後對應的內

Python 爬蟲實例7—— 爬取 新浪軍事新聞

secure host agen cat hand .com cati ica sts 我們打開新浪新聞,看到頁面如下,首先去爬取一級 url,圖片中藍色圓圈部分 第二zh張圖片,顯示需要分頁,

python入門函數的定義

函數 高階函數 python中函數的定義以def開頭,後面跟函數定義的名稱和())‘括號中定義參數’ 以冒號開始,並且進行縮放,return結束如: def hello (ming): print ming return 傳遞參數: ming=[1,2,3]m

玩轉python7python多協程,多線程的比較

用戶體驗 time() cut 過程 RR 至少 執行 結果 關鍵字 前段時間在做一個項目,項目本身沒什麽難度,只是數據存在一個數據接口服務商那兒,這就意味著,前端獲取數據需要至少兩次http請求,第一次是前端到後端的請求,第二次是後端到數據接口的請求。有時,後端接收到前端