1. 程式人生 > >全菊變數和菊部變數

全菊變數和菊部變數

王菊這波熱點來得莫名其妙啊,讓我們這些“菊外人”一臉懵逼。

前陣子還自我吐槽了下文章的選題,熱點沒營養,乾貨沒人看。這下好了,找到了熱點與乾貨的完美結合?

是誰的小眼睛,還沒看Crossin老師?

明確地說,我今天就是來蹭熱點話題流量的。(雖然我覺得事件本身也挺有意思的,已成路人粉)

如果你對此感到不適,或對於變數作用域的相關概念已瞭然於心,那後面的內容就不必看了,謝謝!

但根據我的經驗,幾乎所有的程式設計學習者在開始用函式不久之後,都踩過區域性變數的坑。幾乎每個星期,都會有人在答疑群、知識星球、論壇、微博上問到關於作用域使用不當而導致的問題。(昨天我在微博上剛回答了一個)

所以,如果通過這個略有點惡趣味的熱點事件能讓你記住“全域性變數”、“區域性變數”、“形參”、“實參”、“變數作用域”

這幾個概念,我覺得也挺好啊。

這裡再幫大家理一下。

首先來看這樣一段程式碼:

def func(x):
    print('x =', x)
    y = 10
    x  = y
    print('x =', x)
    return x

a = 5
b = func(a)
print('a =', a)
print('b =', b)

輸出:

x = 5
x = 15
a = 5
b = 15

這裡,函式 func 的形參是 x,它只在函式內部有效,也就是作用域僅在函式中,如果在外部呼叫它,就會報錯。變數 a 作為實參傳遞給函式 func,所以函式裡 x 的值就是 a 的值,但 x 不是 a

,只是現在它倆一樣。變數 y 是函式中定義的區域性變數,它的作用域同樣也僅在函式中。對 x 進行賦值之後,x 的值發生了變化,但不會影響實參 a 的值。函式的返回值是 x 的值,並賦值給了外部的變數 b,所以 b 的值就是 x 的值,但 b 不是 x,此時 x 已不存在。

理解了上面幾條之後,我們再修改一下函式:

def func(x):
    print('x =', x)
    x = 10
    x  = x
    print('x =', x)
    return x

x = 5
func(x)
print('x =', x)

輸出:

x = 5
x = 20
x = 5

解讀一下:函式 func 的形參是 x外部變數 x 作為實參傳遞給函式 func,所以函式裡 x 的值就是外部 x 的值,但這兩個 x 是兩個不同的變數,只是現在值一樣。變數 x 在函式中被重新賦值 10,但不會影響外部變數 x 的值。對 x 自身做了累加,此時 x 變成 20。函式的返回值是 x 的值,但沒有賦值給任何變數,所以此返回值沒任何作用,函式結束。外部的變數 x 仍然是一開始的值 5。但在初學階段,不建議你這麼給變數命名,可能會把自己繞進去。把程式碼寫清楚,多定義幾個變數,多分幾行程式碼,反正也不要錢。(除非你是做區塊鏈程式開發)

那如果要在函式內部修改外部的變數可不可以呢?

可以,用全域性變數。

def func():
    global x
    x = 10

x = 5
func()
print('x =', x)

輸出:

x = 10

在函式中宣告 global x,程式就會知道這個 x 是一個全域性變數。此時的 x 就是外部的 x,給它賦值的結果自然在函式結束後依然有效。但這種情況下,你不能再同時將 x 設定為函式的形參。

如果你僅僅需要在函式內部讀取外部的引數值而不用修改它的值,那麼 global 的宣告就不再需要。

def func():
    y = x
    print('y =', y)

x = 5
func()
print('x =', x)

輸出:

y = 5
x = 5

寫入時 global 的必要在於區分全域性變數和區域性變數,而讀取不存在這樣的問題。

以上就是關於全域性變數、區域性變數、形參、實參、變數作用域的一些小知識點,更多內容可以檢視我們的入門教程。公眾號“Crossin的程式設計教室”裡回覆關鍵字 python

最後留一個思考題:

def func(m):
    m[0] = 20
    m = [4, 5, 6]
    return m

l = [1, 2, 3]
func(l)
print('l =', l)

思考一下輸出會是什麼?

然後自己在電腦上或者我們的線上編輯器 Crossin的程式設計教室 - 線上Python編輯器 裡輸入程式碼執行下看看結果,再想想為什麼。

歡迎留言給出你的解釋。

════其他文章及回答:

歡迎搜尋及關注:Crossin的程式設計教室