Python 不區分變數定義和賦值,是否是設計上的缺陷?

時間 2021-05-30 23:52:11

1樓:naiveman

以下是基於對 A Discipline of Programming 第10章的部分理解,扯出來的淡。

是缺陷。

定義乙個變數是說我建立了乙個新的要關心的東西(名字/狀態空間中的乙個新維度)。

還有乙個容易一起混了的東西就是初始化。初始化和賦值是不同的概念。初始化之前,我定義的東西是不可被使用/引用的(求它的右值/左值),除非引用它是為了初始化它。

初始化即賦予乙個名字以型別和值(狀態),是乙個從無到有的過程。

而賦值則是"改變"乙個東西的狀態,乙個東西得先有原始的狀態,然後才能談改變狀態。

如果定義/宣告,初始化,賦值全用一種表示方法,不做區分。

結果就是連直接給外層變數賦值都做不到,因為內層本意想寫個賦值,會被當成建立內層的區域性變數。

只能重新把宣告設計回來,整出個 nonlocal 宣告。(nonlocal 還跟 global不一樣,真神秘啊。。。)

2樓:許成

我覺得應該是缺陷吧,考慮如下情形

variable = 10

bla bla bla...

varable = 3//此處由於拼寫,少打了個i,認為是新變數variable += 16

計算錯誤

3樓:騰飛

初學Python,有幾年c++經驗,我說幾句我理解的。

對於任何變數來說,他都應該遵循最小作用域,既然Python不區分賦值既建立,那好那我就建立吧!別的我不管,你想用其他作用域的,好吧!你指定吧!

至於說為什麼賦值既建立,可能是因為Python沒有強制要求宣告資料型別的緣故吧!至於說優化,預設是引用形式,只是記憶體效能方面的優化吧!

4樓:Coldwings

因為python中所有東西都是物件,賦值其實只是引用繫結,所以這個情況某種意義上是必然的。

這也與python遵循的基本原則有關。如果遵守簡單唯一表示的原則,那麼並沒有什麼不方便的地方;如果說這個原則不好,那也沒辦法了……

5樓:莫等閒

在foo2中沒有辦法改變foo中a的值,這能否說因為python不區分變數定義和賦值從而導致的乙個缺陷?python3引入的nonlocal恰好證明了這一點?

我想說的是,你從乙個錯誤的論據匯出了乙個正確的結論。。

Python的name rebinding(assign to)機制的確有缺陷,只能rebind到local和module-global,而不能rebind到outer scope。

但Python是有變數宣告的,比如global語句就是用來繫結global變數的,而local宣告是隱式的。Python 3新加的nonlocal修補了不能繫結到outer scope的問題。

PEP 3104 -- Access to Names in Outer Scopes

6樓:Lucian Kaltz

最近主要用Python,弱雞來試著回答一下。對3不熟只說2。

1,關於所謂的不區分變數定義和賦值。

Python的namespace是乙個類字典(或者就是字典,忘記了)的東西,在操作上很類同對字典的鍵值對新增和修改。

2,為什麼設計成這樣。

在我看來這樣的設計無疑幫助了解耦。全域性(或者外部)變數或者依賴越多程式的可讀性和維護性就越差。習慣這種全域性思路可能是為了某些目的(比如做題)需要對程式進行很大程度的hack或者除錯,往往只需要跑一次能過就行了而並不在意後續的維護,顯然與該設計的初衷是不同的。

(這種hack也不是什麼好習慣

7樓:

這個不能算缺陷吧...想實現這種功能應該是有其它的辦法來實現的。對於有些語言,比如C來說,函式是不可以巢狀的。

我倒是覺得Python不區分宣告和賦值的話,有些地方變數名拼寫錯了,執行也可能不報錯,然後就出現各種神奇的bug了。

程式語言為什麼區分常量和變數?

野龍 即使在實現上無區別,即使不存在優化問題,常量也是有用的。用途就是,明確的告訴你這個量不應該被改變,而且編譯器會保證你不會不小心去改變這個量。當然,你非要給cast成非常量來修改,編譯器也拿你沒轍就是了 李登淳 常量更容易優化,我自己寫的那個孱弱的編譯器只能優化常量。事實上很多編譯器能做到讓常量...

Rust的設計中為什麼要區分不可變變數和常量?

Tracy Liang 剛剛在學習,同樣有這個疑問。const 在編譯期確定,可能是字面值,指令運算元。不占用資料段,不在堆疊,靜態區等記憶體空間。let 是執行期佔記憶體空間的,有實體,一般都有位址。只是不可變,在初始化就確定了,但是唯讀。我是不知道這種唯讀變數的意義。 套路小迷糊 對於初級玩家來...

變數的宣告 定義 賦值和初始化有什麼區別?

迎風凌亂 Declaring a variable reserves a name and some space in memory for a variable of the specified type,but doesn t give it a value.Initializing gives...