成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

學(xué)習(xí)用Python編程時要避免的3個錯誤

開發(fā) 后端
為了讓初學(xué) Python 的程序員避免犯同樣的錯誤,以下列出了我學(xué)習(xí) Python 時犯的三種錯誤。這些錯誤要么是我長期以來經(jīng)常犯的,要么是造成了需要幾個小時解決的麻煩。

 

這些錯誤會造成很麻煩的問題,需要數(shù)小時才能解決。

當(dāng)你做錯事時,承認錯誤并不是一件容易的事,但是犯錯是任何學(xué)習(xí)過程中的一部分,無論是學(xué)習(xí)走路,還是學(xué)習(xí)一種新的編程語言都是這樣,比如學(xué)習(xí) Python。

為了讓初學(xué) Python 的程序員避免犯同樣的錯誤,以下列出了我學(xué)習(xí) Python 時犯的三種錯誤。這些錯誤要么是我長期以來經(jīng)常犯的,要么是造成了需要幾個小時解決的麻煩。

年輕的程序員們可要注意了,這些錯誤是會浪費一下午的!

1、 可變數(shù)據(jù)類型作為函數(shù)定義中的默認參數(shù)

這似乎是對的?你寫了一個小函數(shù),比如,搜索當(dāng)前頁面上的鏈接,并可選將其附加到另一個提供的列表中。

  1. def search_for_links(page, add_to=[]): 
  2.  
  3.     new_links = page.search_for_links() 
  4.  
  5.     add_to.extend(new_links) 
  6.  
  7.     return add_to  

從表面看,這像是十分正常的 Python 代碼,事實上它也是,而且是可以運行的。但是,這里有個問題。如果我們給 add_to 參數(shù)提供了一個列表,它將按照我們預(yù)期的那樣工作。但是,如果我們讓它使用默認值,就會出現(xiàn)一些神奇的事情。

試試下面的代碼:

  1. def fn(var1, var2=[]): 
  2.  
  3.     var2.append(var1) 
  4.  
  5.     print var2 
  6.  
  7. fn(3) 
  8.  
  9. fn(4) 
  10.  
  11. fn(5)  

可能你認為我們將看到:

  1. [3] 
  2.  
  3. [4] 
  4.  
  5. [5]  

但實際上,我們看到的卻是:

  1. [3] 
  2.  
  3. [3, 4] 
  4.  
  5. [3, 4, 5]  

為什么呢?如你所見,每次都使用的是同一個列表,輸出為什么會是這樣?在 Python 中,當(dāng)我們編寫這樣的函數(shù)時,這個列表被實例化為函數(shù)定義的一部分。當(dāng)函數(shù)運行時,它并不是每次都被實例化。這意味著,這個函數(shù)會一直使用完全一樣的列表對象,除非我們提供一個新的對象:

  1. fn(3, [4]) 
  1. [4, 3]  

答案正如我們所想的那樣。要想得到這種結(jié)果,正確的方法是:

  1. def fn(var1, var2=None): 
  2.  
  3.     if not var2: 
  4.  
  5.         var2 = [] 
  6.  
  7.     var2.append(var1)  

或是在***個例子中:

  1. def search_for_links(page, add_to=None): 
  2.  
  3.     if not add_to: 
  4.  
  5.         add_to = [] 
  6.  
  7.     new_links = page.search_for_links() 
  8.  
  9.     add_to.extend(new_links) 
  10.  
  11.     return add_to  

這將在模塊加載的時候移走實例化的內(nèi)容,以便每次運行函數(shù)時都會發(fā)生列表實例化。請注意,對于不可變數(shù)據(jù)類型,比如元組、字符串、整型,是不需要考慮這種情況的。這意味著,像下面這樣的代碼是非常可行的:

  1. def func(message="my message"): 
  2.  
  3. print message  

2、 可變數(shù)據(jù)類型作為類變量

這和上面提到的***一個錯誤很相像。思考以下代碼:

  1. class URLCatcher(object): 
  2.  
  3.     urls = [] 
  4.  
  5.     def add_url(self, url): 
  6.  
  7.         self.urls.append(url)  

這段代碼看起來非常正常。我們有一個儲存 URL 的對象。當(dāng)我們調(diào)用 add_url 方法時,它會添加一個給定的 URL 到存儲中。看起來非常正確吧?讓我們看看實際是怎樣的:

  1. a = URLCatcher() 
  2.  
  3. a.add_url('http://www.google.com'
  4.  
  5. b = URLCatcher() 
  6.  
  7. b.add_url('http://www.bbc.co.hk' 

b.urls:

  1. ['http://www.google.com''http://www.bbc.co.uk'

a.urls:

  1. ['http://www.google.com''http://www.bbc.co.uk'

等等,怎么回事?!我們想的不是這樣啊。我們實例化了兩個單獨的對象 a 和 b。把一個 URL 給了 a,另一個給了 b。這兩個對象怎么會都有這兩個 URL 呢?

這和***個錯例是同樣的問題。創(chuàng)建類定義時,URL 列表將被實例化。該類所有的實例使用相同的列表。在有些時候這種情況是有用的,但大多數(shù)時候你并不想這樣做。你希望每個對象有一個單獨的儲存。為此,我們修改代碼為:

  1. class URLCatcher(object): 
  2.  
  3.     def __init__(self): 
  4.  
  5.         self.urls = [] 
  6.  
  7.     def add_url(self, url): 
  8.  
  9.         self.urls.append(url)  

現(xiàn)在,當(dāng)創(chuàng)建對象時,URL 列表被實例化。當(dāng)我們實例化兩個單獨的對象時,它們將分別使用兩個單獨的列表。

3、 可變的分配錯誤

這個問題困擾了我一段時間。讓我們做出一些改變,并使用另一種可變數(shù)據(jù)類型 – 字典。

  1. a = {'1'"one"'2''two'

現(xiàn)在,假設(shè)我們想把這個字典用在別的地方,且保持它的初始數(shù)據(jù)完整。

  1. b = a 
  2.  
  3. b['3'] = 'three'  

簡單吧?

現(xiàn)在,讓我們看看原來那個我們不想改變的字典 a:

  1. {'1'"one"'2''two''3''three'

哇等一下,我們再看看 b?

  1. {'1'"one"'2''two''3''three'

等等,什么?有點亂……讓我們回想一下,看看其它不可變類型在這種情況下會發(fā)生什么,例如一個元組:

  1. c = (2, 3) 
  2.  
  3. d = c 
  4.  
  5. d = (4, 5)  

現(xiàn)在 c 是 (2, 3),而 d 是 (4, 5)。

這個函數(shù)結(jié)果如我們所料。那么,在之前的例子中到底發(fā)生了什么?當(dāng)使用可變類型時,其行為有點像 C 語言的一個指針。在上面的代碼中,我們令 b = a,我們真正表達的意思是:b 成為 a 的一個引用。它們都指向 Python 內(nèi)存中的同一個對象。聽起來有些熟悉?那是因為這個問題與先前的相似。其實,這篇文章應(yīng)該被稱為「可變引發(fā)的麻煩」。

列表也會發(fā)生同樣的事嗎?是的。那么我們?nèi)绾谓鉀Q呢?這必須非常小心。如果我們真的需要復(fù)制一個列表進行處理,我們可以這樣做:

  1. b = a[:] 

這將遍歷并復(fù)制列表中的每個對象的引用,并且把它放在一個新的列表中。但是要注意:如果列表中的每個對象都是可變的,我們將再次獲得它們的引用,而不是完整的副本。

假設(shè)在一張紙上列清單。在原來的例子中相當(dāng)于,A 某和 B 某正在看著同一張紙。如果有個人修改了這個清單,兩個人都將看到相同的變化。當(dāng)我們復(fù)制引用時,每個人現(xiàn)在有了他們自己的清單。但是,我們假設(shè)這個清單包括尋找食物的地方。如果“冰箱”是列表中的***個,即使它被復(fù)制,兩個列表中的條目也都指向同一個冰箱。所以,如果冰箱被 A 修改,吃掉了里面的大蛋糕,B 也將看到這個蛋糕的消失。這里沒有簡單的方法解決它。只要你記住它,并編寫代碼的時候,使用不會造成這個問題的方式。

字典以相同的方式工作,并且你可以通過以下方式創(chuàng)建一個昂貴副本:

  1. b = a.copy() 

再次說明,這只會創(chuàng)建一個新的字典,指向原來存在的相同的條目。因此,如果我們有兩個相同的列表,并且我們修改字典 a 的一個鍵指向的可變對象,那么在字典 b 中也將看到這些變化。

可變數(shù)據(jù)類型的麻煩也是它們強大的地方。以上都不是實際中的問題;它們是一些要注意防止出現(xiàn)的問題。在第三個項目中使用昂貴復(fù)制操作作為解決方案在 99% 的時候是沒有必要的。你的程序或許應(yīng)該被改改,所以在***個例子中,這些副本甚至是不需要的。 

責(zé)任編輯:龐桂玉 來源: Python開發(fā)者
相關(guān)推薦

2017-08-17 09:07:45

Python編程代碼

2021-04-29 15:29:52

機器學(xué)習(xí)人工智能AI

2021-04-22 08:00:00

人工智能機器學(xué)習(xí)數(shù)據(jù)

2021-03-09 09:52:55

技術(shù)React Hooks'數(shù)據(jù)

2018-07-11 05:24:05

機器學(xué)習(xí)人工智能數(shù)據(jù)

2023-01-09 15:16:17

2017-08-02 16:47:43

數(shù)據(jù)數(shù)據(jù)收集數(shù)據(jù)分析

2021-12-02 18:07:53

云網(wǎng)絡(luò)部署云端云計算

2018-03-17 09:04:35

2023-05-11 09:06:50

錯誤IT培訓(xùn)

2023-06-07 07:43:06

APIVue 2Vue 3

2021-12-03 15:00:18

人工智能自然語言機器學(xué)習(xí)

2024-01-26 06:33:06

數(shù)據(jù)策略決策

2022-03-08 09:31:48

云配置云安全

2013-04-23 10:57:27

iOS開發(fā)App icon設(shè)計

2021-06-28 10:12:34

云計算云平臺云計算架構(gòu)

2013-08-27 14:44:05

App icon設(shè)計ASO應(yīng)用商店優(yōu)化app營銷推廣

2020-03-02 08:00:00

微服務(wù)架構(gòu)軟件開發(fā)

2015-05-22 09:05:00

云部署云部署錯誤

2021-04-08 13:50:54

云計算云計算產(chǎn)業(yè)云應(yīng)用
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产欧美一区二区三区在线看蜜臀 | 精品天堂| 国产精品久久二区 | 美女视频一区二区三区 | 久久亚洲春色中文字幕久久久 | 精品亚洲一区二区 | 免费同性女女aaa免费网站 | 国产精品观看 | 成人一区二区三区在线观看 | 影音先锋中文字幕在线观看 | 无人区国产成人久久三区 | 91在线精品秘密一区二区 | 国产色| 欧美中文一区 | 日韩电影一区二区三区 | 羞羞视频一区二区 | 日本一区二区三区四区 | 成人精品一区亚洲午夜久久久 | 免费一区二区三区 | 97精品一区二区 | 三级在线免费观看 | www.色.com| 久久精品国产99国产 | 成人在线免费视频观看 | 午夜免费观看网站 | 亚洲在线视频 | 成人国产一区二区三区精品麻豆 | 午夜精品 | 免费簧片视频 | 国产欧美一级 | 久久99精品久久久久久琪琪 | 国产精品成人一区二区三区 | 午夜丰满寂寞少妇精品 | 婷婷精品 | 国产成人精品久久二区二区 | 亚洲一区二区视频 | 亚洲一二视频 | 久草在线影 | 天堂视频免费 | 在线色网 | 日本亚洲精品成人欧美一区 |