本節將開始介紹 Python 語言的基本語義。與上一節介紹的語法相反,語言的語義涉及語句的含義。與討論語法一樣,這裏我們將預覽 Python 中一些基本的語義解釋,以爲您提供更好的參考框架,以幫助理解以下各節中的代碼。
本節將介紹變量和對象的語義,這是在Python腳本中存儲、引用和操作數據的主要方式。
Python 變量是指針
在 Python 中給變量賦值,容易到只需將變量名放在等號(=)的左側:
# assign 4 to the variable x
x = 4
這看上去很簡單,但是如果您對該操作的真正含義理解有誤,那麼 Python 的工作原理可能會令人困惑。我們將在這裏進行簡要地探討。
在許多編程語言中,變量被視爲將數據放入其中的容器或存儲桶。例如在C語言中:
// C code
int x = 4;
您實際上是定義一個名爲 x 的“內存桶”,並將值 4 放入其中。相反,在Python 中,最好不要將變量視爲容器,而應將其視爲指針。所以在Python 中,當您編寫:
x = 4
您實際上是定義(或者創建)一個名爲 x 的指針(即 python 中的變量),該指針指向包含值 4 的存儲桶。請注意這裏的意義:由於Python 變量能夠指向各種對象,因此無需先“聲明”該變量,甚至不需要該變量總是指向相同類型的信息(即不需要聲明變量的類型)!這就是人們所說的 Python 是動態類型的原因:變量名可以指向任何類型的對象。因此,在Python中,您可以執行以下操作:
#這裏 x 第一次出現會首先創建名稱爲 x 的變量,並指向對象數字 1.
x = 1 # x is an integer
x = 'hello' # now x is a string
x = [1, 2, 3] # now x is a list
然而靜態類型語言的使用者可能會覺得少了像 C 語言中聲明變量所附帶的類型的安全性,
int x = 4;
這種動態類型是使 Python 能如此快速地編寫和易於閱讀的代碼的特徵之一。
您所需要注意的是這種“變量作爲指針”方法的後果。如果我們有兩個指向同一個可變對象的變量名,那麼更改一個也會同時更改另一個!例如,讓我們創建和修改列表:
x = [1, 2, 3]
y = x
我們創建了兩個變量 x 和 y,它們都指向同一對象。因此,如果我們通過兩個變量之一來修改列表,我們將看到“其他”列表也將被修改:
print(y)
[1, 2, 3]
x.append(4) # append 4 to the list pointed to by x
print(y) # y's list is modified as well!
[1, 2, 3, 4]
如果您錯誤地將變量視爲包含數據的存儲容器,則此行爲可能會造成理解上的混亂。但是,如果您正確地將變量視爲對象的指針,則此行爲的意義就很容易理解了。
還要注意,如果我們使用 “=” 爲 x 賦另一個值,則不會影響 y 的值—賦值只是改變變量指向的對象:
x = 'something else'
print(y) # y is unchanged
[1, 2, 3, 4]
同樣,完全可以這樣理解,將 x 和 y 視爲指針(理解這個需要一點點 C 語言的知識),而將“=”運算符視爲改變變量所指向的操作。
您可能在想,這種指針的用法是否會使 Python 中的算術運算難以跟蹤,但是 Python 的設計使這不是問題。 數字,字符串和其他簡單類型是不可改變的:您不能更改它們的值–您只能更改變量指向的對象。 因此,例如,執行以下操作是絕對安全的:
x = 10
y = x
x += 5 # add 5 to x's value, and assign it to x,執行完這條語句後 x 指向了新的對象15.
print("x =", x)
print("y =", y)
x = 15
y = 10
當我們執行 x += 5 時,我們並沒有修改 x 指向的“10”這個對象的值; 而是更改變量 x 的指向,使其指向具有值 15 的新整數對象。因此,y 的值不受此操作的影響。
一切皆對象
Python 是一種面向對象的編程語言,在 Python 中,一切都是對象。
讓我們詳細說明這意味着什麼。 前面我們看到變量可以理解爲指針,變量名稱本身沒有附加任何類型信息。 這導致一些人錯誤地理解爲 Python 是一種無類型的語言。 但是情況並非如此! 考慮以下:
x = 4
type(x)
int
x = 'hello'
type(x)
str
x = 3.14159
type(x)
float
從上面可以看出 Python 是有類型; 只是類型不是鏈接到變量名的,而是鏈接到對象本身的(即類型信息是和對象綁定在一起的)。
在像 Python 這種的面向對象的編程語言中,對象是一個實體,其中包含數據以及關聯的元數據和/或函數(方法)。 在 Python 中,一切都是對象,這意味着每個實體都有一些元數據(稱爲屬性)和關聯的函數(稱爲方法)。 這些屬性和方法通過點語法( dot syntax)訪問。
例如,在前面我們看到列表有一個 append 方法,該方法將一個條目添加到列表中,並通過點(“.”)語法進行訪問:
L = [1, 2, 3]
L.append(100)
print(L)
[1, 2, 3, 100]
然而你可能預想到諸如列表之類的複合對象具有屬性和方法,但出乎意料的是,在Python中,即使簡單類型也具有屬性和方法。 例如,數值類型具有 real 和 imag 屬性,如果將其視爲複數,則該屬性分別表示實部和虛部:
x = 4.5
print(x.real, "+", x.imag, 'i')
4.5 + 0.0 i
方法與屬性類似,不同之處在於方法是可以使用左括號和右括號調用的函數。 例如,浮點數具有一個稱爲 is_integer 的方法,該方法檢查該值是否爲整數:
x = 4.5
x.is_integer()
False
x = 4.0
x.is_integer()
True
當我們說 Python 中的所有東西都是對象時,我們實際上是說一切都是對象-甚至對象的屬性和方法本身也是具有自身類型信息的對象:
type(x.is_integer)
builtin_function_or_method
我們會發現 Python 的“一切都是對象”設計,這個選擇允許了一些非常方便的語言構造。
本文來自翻譯如下文章,僅用於學習
原文:https://jakevdp.github.io/WhirlwindTourOfPython/03-semantics-variables.html