【入門必看】不理解「物件」?很可能有致命bug:簡單的Python例子告訴你
簡介:越來越多的人要在學習工作中用到『程式設計』這個工具了,其中很大一部分人用的是Python。大部分人只是做做簡單的科研計算、繪圖、辦公自動化或者爬蟲,但—— 這就不需要理解「指標與物件導向」了嗎? 在我看來,新手或外行朋友也需要簡單地理解「物件」概念,本文將先演示一個反例(告訴你不理解將多麼容易犯錯誤),然後淺顯地介紹一下「物件」。
致命bug
小垣坐在電腦前,一臉愁容——這麼簡單的程式,她花了3個小時,硬是沒發現哪裡不對,導致程式不通暢。
她發了幾張截圖給我,說“拍老師,發生甚麼事了?”
我一看,嗷,是班花小垣給我發訊息了,我啪一下站起來了,很快啊!
一共兩個.py
指令碼檔案,一個八十多行,一個九十多行。整體邏輯沒什麼問題,只是有幾處很“荒唐”,究其原因,是小垣沒有理解「物件」這個概念。
看罷,我拋開這個問題,直接甩給她我騰訊會議ID,開始講解起「物件」這個概念來,因為了解了「物件」這個傳統功夫後,其問題自然而然就化解了。
一個簡單的 numpy 反例
我們以 Python 中最常用的矩陣與代數庫 numpy
為例。
import numpy as np
我們現在定義一個長度為 3 的向量 vec_origin
,其中存放 1,2,3
。然後我們列印一下看看。
vec_origin = np.array([1, 2, 3])
print(vec_origin)
列印結果如下。
[1 2 3]
假如我們需要複製一下向量 vec_origin
,那麼,“自然”是做個等號。如下。然後列印一下。
vec_copy = vec_origin
print(vec_copy)
輸出結果為如下。
[1 2 3]
接下來, vec_origin
與 vec_copy
將參與不同的運算任務,其將被加減乘除,還有 賦值 。問題就出在了,如果我們為 vec_copy
賦值,那麼 vec_origin
的值也將被改變。不信你試試下面的程式碼。
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
vec_copy[0] = 9
print("我們只改變了 vec_copy 的值,但是:")
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
輸出結果如下。
vec_origin [1 2 3]
vec_copy [1 2 3]
我們只改變了 vec_copy 的值,但是:
vec_origin [9 2 3]
vec_copy [9 2 3]
但是,vec_origin
的值也跟著改變了。這是為什麼呀!
要知道,我們對變數賦值與複製,是不會改變原值的呀!如下。
a = 1
b = a
print(a) # 1
print(b) # 1
b = 9
print(a) # 1
print(b) # 9
numpy 中的矩陣/向量,是個物件
對於 numpy
來講,我們宣告的矩陣或者向量,並不是一個“數字”那麼簡單,而是一個有「身份證」的『物件』。
一個物件可以有多個名字,但身份證只能有一個。換句話說,身份證才是唯一標識。
對於不是單個數值的數,我們的 =
賦值,只不過是 給物件新增了一個名字罷了。
不信,我們用 python 內建的 id()
函式看看 vec_origin
與 vec_copy
名字是不是一樣的。
print(id(vec_origin))
print(id(vec_copy))
結果如下。
2006971817136
2006971817136
很顯然,二者的身份證是一個,這根本就是同一個向量。
對於 list
、 dict
等等,都是同理。
那麼,該如何複製呢?
我的建議是,你沒有必要去可以背誦方法。不同型別的物件有不同賦值方法。對於 numpy 的向量,我們去網際網路搜尋一下就好,檢索詞:numpy 複製
。
我查到的方法是:使用 np.copy
。
那麼我們試驗一下。
import numpy as np
vec_origin = np.array([1, 2, 3])
vec_copy = np.copy(vec_origin) # 這裡複製
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
vec_copy[0] = 9
print("我們只改變了 vec_copy 的值,但是:")
print("vec_origin", vec_origin)
print("vec_copy", vec_copy)
print(id(vec_origin))
print(id(vec_copy))
結果如下。
vec_origin [1 2 3]
vec_copy [1 2 3]
我們只改變了 vec_copy 的值,但是:
vec_origin [1 2 3]
vec_copy [9 2 3]
2343952817328
2343952817568
如你所見, np.copy
後,是新增了一個物件,而非僅僅是為原物件新增了一個變數名而已。
這是 零基礎程式設計
系列的第一篇文章,之後,我們將用簡單的例子討論:物件導向
、指標
、資料結構
等等基礎概念。我一直認為,新手對這些概念有些許瞭解後,將少走很多很多的彎路。
最後,你問小垣有沒有改好 bug ,那自然是:傳統功夫點到為止!自從她跟我說她有「物件」後,我就再也沒問過她有沒有理解「物件」。
祝各位變得更強。歡迎關注公眾號:Piper蛋窩
,回覆微信
加我微信。歡迎點贊
、點選在看
鼓勵我。
相關文章
- 【Python小白入門必看】Python和VB哪個更簡單?Python
- Java多型的一個簡單入門的例子Java多型
- 用最簡單的話告訴你什麼是ElasticSearchElasticsearch
- 一個資料決策的例子,告訴你這門生意能不能做
- sencha表單入門例子
- 告訴我你的廚房有什麼智慧物件物件
- Python小白必看!新手入門指南Python
- 如何實現一個簡單的雨滴動畫?手把手告訴你動畫
- 12個例子帶你入門Electron
- Nodejs:UDP極簡入門例子NodeJSUDP
- 一個簡單的例子帶你理解HashmapHashMap
- python+flask 編寫一個簡單的登入介面例子PythonFlask
- python+flask編寫一個簡單的登入介面例子PythonFlask
- “金三銀四”告訴你,Python如何從入門到高薪跳槽後月薪2WPython高薪
- 10年網際網路開發者告訴你自學 Java 怎麼入門?Java
- XPATH的簡單例子單例
- Python 簡單入門指北(試讀版)Python
- Java Junit單元測試(入門必看篇)Java
- Azkaban 簡單入門
- postgresql 簡單入門SQL
- SprintBoot簡單入門boot
- Vue簡單入門Vue
- Kafka簡單入門Kafka
- Mysql 簡單入門MySql
- git簡單入門Git
- Espresso 簡單入門Espresso
- Groovy 簡單入門
- drools的簡單入門案例
- 簡單的 Go 入門教程Go
- 三十二張圖告訴你,Jenkins構建Spring Boot 有多簡單~JenkinsSpring Boot
- go語言如何入門?從一個簡單例子開始學起Go單例
- 通過Redux原始碼學習基礎概念一:簡單例子入門Redux原始碼單例
- Jmeter新手入門必看JMeter
- webpack 入門例子Web
- Websocket簡單例子Web單例
- JNI 簡單例子單例
- HttpClient 簡單例子HTTPclient單例
- TensorFlow 的簡單例子單例