中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

學習用Python編程時要避免的3個錯誤分別是什么

發布時間:2021-10-26 17:23:59 來源:億速云 閱讀:154 作者:柒染 欄目:編程語言

這篇文章將為大家詳細講解有關學習用Python編程時要避免的3個錯誤分別是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

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

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

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

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

1、 可變數據類型作為函數定義中的默認參數

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

def search_for_links(page, add_to=[]):      new_links = page.search_for_links()      add_to.extend(new_links)      return add_to

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

試試下面的代碼:

def fn(var1, var2=[]):      var2.append(var1)      print var2  fn(3)  fn(4)  fn(5)

可能你認為我們將看到:

[3]  [4]  [5]

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

[3]  [3, 4]  [3, 4, 5]

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

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

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

def fn(var1, var2=None):      if not var2:          var2 = []      var2.append(var1)

或是在***個例子中:

def search_for_links(page, add_to=None):      if not add_to:          add_to = []      new_links = page.search_for_links()      add_to.extend(new_links)      return add_to

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

def func(message="my message"):  print message

2、 可變數據類型作為類變量

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

class URLCatcher(object):      urls = []      def add_url(self, url):          self.urls.append(url)

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

a = URLCatcher()  a.add_url('http://www.google.com')  b = URLCatcher()  b.add_url('http://www.bbc.co.hk')

b.urls:

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

a.urls:

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

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

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

class URLCatcher(object):      def __init__(self):          self.urls = []      def add_url(self, url):          self.urls.append(url)

現在,當創建對象時,URL 列表被實例化。當我們實例化兩個單獨的對象時,它們將分別使用兩個單獨的列表。

3、 可變的分配錯誤

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

a = {'1': "one", '2': 'two'}

現在,假設我們想把這個字典用在別的地方,且保持它的初始數據完整。

b = a  b['3'] = 'three'

簡單吧?

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

{'1': "one", '2': 'two', '3': 'three'}

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

{'1': "one", '2': 'two', '3': 'three'}

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

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

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

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

列表也會發生同樣的事嗎?是的。那么我們如何解決呢?這必須非常小心。如果我們真的需要復制一個列表進行處理,我們可以這樣做:

b = a[:]

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

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

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

b = a.copy()

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

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

關于學習用Python編程時要避免的3個錯誤分別是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

贞丰县| 东兴市| 天柱县| 迁安市| 昔阳县| 米泉市| 东莞市| 潜山县| 镇康县| 铁岭县| 公安县| 辽阳县| 庆云县| 山东| 福鼎市| 巴青县| 尚义县| 兴业县| 敦煌市| 绥芬河市| 博湖县| 肥东县| 益阳市| 荥经县| 澄迈县| 屯门区| 鲜城| 两当县| 金堂县| 天门市| 新田县| 来安县| 孟连| 仪陇县| 寿宁县| 平遥县| 华池县| 商城县| 突泉县| 余庆县| 台北县|