最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談使用Python變量時(shí)要避免的3個(gè)錯(cuò)誤

 更新時(shí)間:2017年10月30日 08:39:26   投稿:mengwei  
這篇文章主要介紹了淺談使用Python變量時(shí)要避免的3個(gè)錯(cuò)誤,還是比較不錯(cuò)的,涉及部分代碼分析,以及字典的創(chuàng)建等相關(guān)內(nèi)容,需要的朋友可以參考下。

Python編程中經(jīng)常遇到一些莫名其妙的錯(cuò)誤, 其實(shí)這不是語言本身的問題, 而是我們忽略了語言本身的一些特性導(dǎo)致的,今天就來看下使用Python變量時(shí)導(dǎo)致的3個(gè)不可思議的錯(cuò)誤, 以后在編程中要多多注意。

關(guān)于Python編程運(yùn)行時(shí)新手易犯錯(cuò)誤,這里暫不作介紹,詳情參見:Python運(yùn)行的17個(gè)時(shí)新手常見錯(cuò)誤小結(jié)

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

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

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

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

試試下面的代碼:

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

可能你認(rèn)為我們將看到:

[3]
[4]
[5]

但實(shí)際上,我們看到的卻是:

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

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

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

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

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

或是在第一個(gè)例子中:

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

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

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

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

這和上面提到的最后一個(gè)錯(cuò)誤很相像。思考以下代碼:

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

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

a =URLCatcher()
a.add_url('http://www.google.com')
b =URLCatcher()
b.add_url('http://www.pythontab.com')
print(b.urls)
print(a.urls)

結(jié)果:

['http://www.google.com','http://www.pythontab.com']
['http://www.google.com','http://www.pythontab.com']

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

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

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

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

3、 可變的分配錯(cuò)誤

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

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

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

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

簡單吧?

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

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

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

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

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

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

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

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

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

b = a[:]

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

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

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

b = a.copy()

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

可變數(shù)據(jù)類型的麻煩也是它們強(qiáng)大的地方。以上都不是實(shí)際中的問題;它們是一些要注意防止出現(xiàn)的問題。在第三個(gè)項(xiàng)目中使用昂貴復(fù)制操作作為解決方案在 99% 的時(shí)候是沒有必要的。

總結(jié)

以上就是本文關(guān)于淺談使用Python變量時(shí)要避免的3個(gè)錯(cuò)誤的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:python探索之BaseHTTPServer-實(shí)現(xiàn)Web服務(wù)器介紹、Python探索之SocketServer詳解等,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關(guān)文章

  • Python基礎(chǔ)之dict和set的使用詳解

    Python基礎(chǔ)之dict和set的使用詳解

    這篇文章主要為大家詳細(xì)介紹了Python語言中dict和set的使方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Python有一定的幫助,需要的可以參考一下
    2022-08-08
  • Pygame游戲開發(fā)之太空射擊實(shí)戰(zhàn)精靈的使用上篇

    Pygame游戲開發(fā)之太空射擊實(shí)戰(zhàn)精靈的使用上篇

    相信大多數(shù)8090后都玩過太空射擊游戲,在過去游戲不多的年代太空射擊自然屬于經(jīng)典好玩的一款了,今天我們來自己動(dòng)手實(shí)現(xiàn)它,在編寫學(xué)習(xí)中回顧過往展望未來,下面開始講解精靈的使用
    2022-08-08
  • Python導(dǎo)出DBF文件到Excel的方法

    Python導(dǎo)出DBF文件到Excel的方法

    這篇文章主要介紹了Python導(dǎo)出DBF文件到Excel的方法,實(shí)例分析了Python基于win32com模塊實(shí)現(xiàn)文件導(dǎo)出與轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下
    2015-07-07
  • TensorFlow實(shí)現(xiàn)非線性支持向量機(jī)的實(shí)現(xiàn)方法

    TensorFlow實(shí)現(xiàn)非線性支持向量機(jī)的實(shí)現(xiàn)方法

    本篇文章主要介紹了TensorFlow實(shí)現(xiàn)非線性支持向量機(jī)的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • python如何通過正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容

    python如何通過正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容

    這篇文章主要介紹了python通過正則匹配指定字符開頭與結(jié)束提取中間內(nèi)容的操作方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • Python字符串、元組、列表、字典互相轉(zhuǎn)換的方法

    Python字符串、元組、列表、字典互相轉(zhuǎn)換的方法

    這篇文章主要介紹了Python字符串、元組、列表、字典互相轉(zhuǎn)換的方法的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • Python使用一行代碼獲取上個(gè)月是幾月

    Python使用一行代碼獲取上個(gè)月是幾月

    本文介紹的關(guān)于Python時(shí)間日期處理,日期時(shí)間處理在實(shí)際應(yīng)用場景中無處不在,所以這也成了編程語言中必不可少的模塊,本文主要給大家介紹Python使用一行代碼獲取上個(gè)月是幾月的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2018-08-08
  • YOLOv5小目標(biāo)切圖檢測的思路與方法

    YOLOv5小目標(biāo)切圖檢測的思路與方法

    目標(biāo)檢測Yolo算法是非常經(jīng)典且應(yīng)用廣泛的算法,下面這篇文章主要給大家介紹了關(guān)于YOLOv5小目標(biāo)切圖檢測的思路與方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Python單元測試工具doctest和unittest使用解析

    Python單元測試工具doctest和unittest使用解析

    這篇文章主要介紹了Python單元測試工具doctest和unittest使用解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • 詳解Python中的__new__()方法的使用

    詳解Python中的__new__()方法的使用

    本文主要介紹了Python中的__new__()方法的使用的基本知識(shí),本文中給出了基于Python2.x的代碼實(shí)例,需要的朋友可以參考一下
    2015-04-04

最新評論

慈利县| 嘉黎县| 凤城市| 盈江县| 无极县| 赞皇县| 延川县| 陆良县| 合江县| 纳雍县| 荆门市| 铜山县| 扎兰屯市| 武汉市| 同江市| 土默特右旗| 昭苏县| 石楼县| 西贡区| 彩票| 惠州市| 玉溪市| 扬州市| 万州区| 牙克石市| 叙永县| 湘西| 沈丘县| 鲁甸县| 海城市| 钦州市| 永年县| 南宁市| 依兰县| 石狮市| 兴宁市| 石阡县| 香港 | 铜鼓县| 密云县| 宝清县|