a = "abc"b = aa = "XYZ"print(b)print(a)
回複內容:
JVM和CLR的那種stack和heap的區分應該是沒有的,按這個算python應該只有heap,但是有常量池。陳儒老師和賴勇浩老師的《Python源碼剖析》有詳細的介紹這方面的知識。
================
多年不讀源碼剖析,我的說法是有問題的,評論裡 RednaxelaFX 有修正:“CPython不但有棧有堆而且棧還有native stack和PyFrameObject構成的解譯器棧兩邊”。聲明:以下提及的Python實現或相關細節概念均特指CPython
1. 首先解決題主demo代碼裡面的疑惑
(沒寫過compiler)不管是Python還是C, 很重要的一個概念就是name 和 object。在Python裡面指派陳述式有非常簡潔的抽象概念,如下
Assignment expression in Python have two things in common:
- Create a new object
- build a connection between that new object and a name
題主可以思考既然 a = 1 在Python中是assignment expression,那麼def func(): pass 是不是一個指派陳述式呢?(請緊扣上面關於賦值運算式的兩條概念) 我並沒有說題外話,只是在協助題主更深刻的理解demo代碼裡面關於賦值過來賦值過去的一些疑惑。
一方面為了更好的利用高效率的記憶體,另一方面為了釋放把程式員從各種記憶體管理的細節中解放,更好的關注“商務邏輯”,有了GC和一些很爽的技術,比方說reference
In [8]: string_1 = "EOF"In [9]: string_2 = "EOF"In [11]: print "address 1: %x" % id(string_1)address 1: 7f2517898530In [12]: print "address 2: %x" % id(string_2)address 2: 7f2517898530
請不要使用Java那一套思想來理解python。編譯器不懂。不發表評論。
但是字串在python裡面是常量,實現大概是一個常量池之類的東西。
str的值不能被改變,能改變的只是變數標記指向的地址。
a = "str"b = "str"a is b
記住一點:CPython為例,所有變數都是一個PyObject*,也就是指標,而所有指派陳述式都是將一個對象的地址賦值給它,其實不光是變數,容器裡面的也是,比如list和dict的元素等,所以你這裡的代碼就相當於:
PyObject *a = new_str("abc");
PyObject *b = a;
a = new_str("xyz");
當然內部不是用new_str這個函數,具體名字我忘啦
python引用的問題我曾經在一個群做過分享,有人整理了聊天記錄:
python對象的引用-python2群20130223群內授課記錄
可以看看,歡迎討論看到這個問題,如鯁在喉,想說什麼,又不知道說什麼。。。。
1。a 和 b 是兩個不同的變數, a = b 是變數賦值啊,不是引用賦值。當然列印結果是不一樣的。這是python文法的問題。
2。堆和棧, 當堆和棧兩個放在一起說的時候,當然指的是C語言中那個特殊的堆和特殊的棧,而不是資料結構中的那個棧。所以有些答案不對題。
3。python語言和python虛擬機器的問題, python虛擬機器只是python語言的一個實現,如果說這個虛擬機器用C寫,那當然是有堆和棧,問題是,有手冊定義了具體實現的方法嗎?
4。如果說python語言本身, 問題,你看到哪本python的書裡講到堆和棧,我的意思是,刨去語言實現部分。
所以,這個問題麼。。。少年,請搞清基本概念再來討論吧。 a 和b應該只是一個標籤