這段python代碼如何理解?解釋器是如何實現這種結果的?

在python2和python3下均有發現這個情況。

在循環中 to 已經不是range對象了,但是下一次循環仍然不會有錯誤。

比如第一次循環後to==0,但是仍然可以繼續循環。

用id(to)考察過每次循環,當to是很大的數據時相鄰兩者之差並不存在規律,說明不是像C的數組一樣通過等間距地址移動來訪問的:如下


值為 range 的 to,在 for 循環里只被引用過一次,故而:

to = range(10)
for x in to:
print(x)

等價於

to = range(10)
it = iter(to)
while True:
try:
x = it.next()
except StopIteration:
break
print(x)

所以你的 to,在 for 開始的時候引用一遍以後 for 就不需要再依賴它了,後面 to 也就被循環改寫了也沒關係,所以你把上面的 x 換成 to 也不會影響迭代。

團隊里誰這麼寫代碼估計要被噴死,不要寫任何可能有歧義的代碼,不要去挑戰解釋器/編譯器/標準的實現細節,當你不確定時,記不得符號優先順序就加括弧,變數作用域含糊就換個名字,別自己覺得好像是這樣就行,別給閱讀的人造成負擔,別給你自己找麻煩。

再 id 問題,python 對象都是分配出來的,id就是該對象的內存指針地址:

id(object)

Return the 「identity」 of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

CPython implementation detail: This is the address of the object in memory.

新分配出來的對象,你每個long 都是一個新對象,new 出來的,地址當然不連續,並且是隨機的,但是他們的指針在 list 里是連續的,你可以理解成 C++ 的:

int *array[] = { new int(10), new int(20), new int(30) };

而不是:

int array[] = { 10, 20, 30 };

小整數的 id 是均勻的,每個小整數的 id 間隔 12 位元組看下面:

&>&>&> x, y, z = 1, 2, 3
&>&>&> id(x), id(1)
(30635864, 30635864)
&>&>&> id(y), id(2)
(30635852, 30635852)
&>&>&> id(z), id(3)
(30635840, 30635840)
&>&>&> w = x + y
&>&>&> id(w), id(3)
(30635840, 30635840)

因為 256 (好像是這個閾值)以下的整數的 object 被預先分配出來了,並且都緊挨著放,除了小整數被預先分配出來外,還有小字元串,他們是不會被釋放的,使用完了還在那裡,並且他們的地址都是連續的,間隔相同的。

但是超過閾值的整數用完了都會被釋放,比如:

&>&>&> id(10000)
91817640
&>&>&> id(10001)
91817640
&>&>&> id(10002)
91817640

三個整數id都一樣?因為每次都分配新的來,用完就釋放了,按照 python內存分配器的規律,再分配同樣大小的內存,會得到剛才釋放的指針,所以生命周期不一樣的對象有可能得到相同的 id。


不謝邀,看不懂,也不想分析奇怪的代碼。


to只是一個reference而已。在 for to in to 裡面,Python的virtual machine先抓住了原本to指向的range物件,然後紀錄了該物件的位址並增加reference counter。接著把range物件產生的整數用to變數指向它,所以range物件是被pvm保留起來了。


什麼人寫出這麼操蛋的代碼的?


to 只在 in 後面調用一次 a 每次循環都 -1 減到 0 循環退出


因為to在tos to在co_names


我就想知道,中間那一堆if else有啥用?


參見iterable與iterator,for in僅僅是一個語法糖而已。

不過你這種寫法,就算被認為是UB也一點不奇怪。


推薦閱讀:

如何深入了解python原理?
python寫的CGI腳本,用print為什麼不是列印到控制台,而是發送到客戶端?
Python下使用matplotlib庫時,如何與LaTeX結合起來?
用Python寫過哪些「腦洞大開」的小工具?
在數據分析方面,比起python,excel的局限性在哪?

TAG:Python | 編程學習 |