Python程式設計中常遇到一些莫名其妙的錯誤, 其實這不是語言本身的問題, 而是我們忽略了語言本身的一些特性導致的,今天就來看下使用Python變數時導致的3個不可思議的錯誤, 以後在程式設計上要多注意。
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): ifnot var2: var2 =[] var2.append(var1)
或是在第一個例子中:
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
這將在模組載入的時候移走實例化的內容,以便每次運行函數時都會發生列表實例化。請注意,對於不可變資料類型,例如元組、字串、整數,是不需要考慮這種情況的。這意味著,像下面這樣的程式碼是非常可行的:
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.pythontab.com') print(b.urls) print(a.urls)
結果:
['http://www.google.com','http://www.pythontab.com'] ['http://www.google.com','http://www.pythontab.com']
等等,怎麼回事? !我們想的不是這樣。我們實例化了兩個單獨的物件 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變數易錯點介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Arraysinpython,尤其是Vianumpy,ArecrucialInsCientificComputingfortheireftheireffertheireffertheirefferthe.1)Heasuedfornumerericalicerationalation,dataAnalysis和Machinelearning.2)Numpy'Simpy'Simpy'simplementIncressionSressirestrionsfasteroperoperoperationspasterationspasterationspasterationspasterationspasterationsthanpythonlists.3)inthanypythonlists.3)andAreseNableAblequick

你可以通過使用pyenv、venv和Anaconda來管理不同的Python版本。 1)使用pyenv管理多個Python版本:安裝pyenv,設置全局和本地版本。 2)使用venv創建虛擬環境以隔離項目依賴。 3)使用Anaconda管理數據科學項目中的Python版本。 4)保留系統Python用於系統級任務。通過這些工具和策略,你可以有效地管理不同版本的Python,確保項目順利運行。

numpyarrayshaveseveraladagesoverandastardandpythonarrays:1)基於基於duetoc的iMplation,2)2)他們的aremoremoremorymorymoremorymoremorymoremorymoremoremory,尤其是WithlargedAtasets和3)效率化,效率化,矢量化函數函數函數函數構成和穩定性構成和穩定性的操作,製造

數組的同質性對性能的影響是雙重的:1)同質性允許編譯器優化內存訪問,提高性能;2)但限制了類型多樣性,可能導致效率低下。總之,選擇合適的數據結構至關重要。

到CraftCraftExecutablePythcripts,lollow TheSebestPractices:1)Addashebangline(#!/usr/usr/bin/envpython3)tomakethescriptexecutable.2)setpermissionswithchmodwithchmod xyour_script.3)

numpyArraysareAreBetterFornumericalialoperations andmulti-demensionaldata,而learthearrayModuleSutableforbasic,內存效率段

numpyArraySareAreBetterForHeAvyNumericalComputing,而lelethearRayModulesiutable-usemoblemory-connerage-inderabledsswithSimpleDatateTypes.1)NumpyArsofferVerverVerverVerverVersAtility andPerformanceForlargedForlargedAtatasetSetsAtsAndAtasEndCompleXoper.2)

ctypesallowscreatingingangandmanipulatingc-stylarraysinpython.1)usectypestoInterfacewithClibrariesForperfermance.2)createc-stylec-stylec-stylarraysfornumericalcomputations.3)passarraystocfunctions foreforfunctionsforeffortions.however.however,However,HoweverofiousofmemoryManageManiverage,Pressiveo,Pressivero


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

記事本++7.3.1
好用且免費的程式碼編輯器