python中的類型是怎麼實現不用顯式定義,動態確定數據類型的?


動態類型:類型與對象而非變數相關聯。另一個說法:變數沒有類型,但是對象有類型。

在實現上,所有的數據都包裝成「對象」(如C Python中是PyObject結構體)。

為了簡化情況,我們以Lua為例。Lua中與PyObject對應的是lua_TValue,它是一個結構體。tt_表示類型(用int「編碼」了);value_表示對應類型的值。

#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8

#define LUA_NUMTAGS 9

再簡化情況,一個比較naive的scheme實現中:

enum type { integer, pair, string, vector, ... };

typedef struct value *SCM;

struct value {
enum type type;
union {
int integer;
struct { SCM car, cdr; } pair;
struct { int length; char *elts; } string;
struct { int length; SCM *elts; } vector;
...
} value;
};

聲明時產生一個SCM指針,而不知道它的type和value。

如果賦了一個integer的值,如(set x 1),引擎內部會有這樣的變化:x -&> type = integer, x-&>value.integer = 1。


3. Data model


python萬物皆對象

print type(1)
print type("1")
print issubclass(int,object)
print isinstance(int,object)
print issubclass(str,object)
print isinstance(str,object)


我用我專欄里的一篇文章來仔細講講:

專欄鏈接:給妹子講python,歡迎大家關注,提意見!

回答這個問題,就得談談python中的對象引用機制和動態類型。的確,python使用變數的時候都沒有聲明變數的類型,這一點和C語言不同。但是,變數還可以工作,因為在python中類型是在運行的過程中自動決定的,而不是通過代碼聲明的,這意味著沒有必要事先聲明變數。

在python中,我們要明確一個概念:變數名和對象是劃分開的,變數名永遠沒有任何關聯的類型信息,類型是和對象關聯的,而不存在於變數名中。一個變數名當第一次被賦值的時候被創建,而當新的賦值表達式出現時,他會馬上被當前新引用的對象所代替。這就是python所謂的動態類型機制。具體看一個例子:

a = abcde
print(a)
a = [1,2,3,4,5]
print(a)

abcde
[1, 2, 3, 4, 5]

結合上面這個例子,我們再來從頭仔細理一理:

1、創建了一個字元串對象』abcde』,然後創建了一個變數a,將變數a和字元串對象』abcde』相連接,

2、之後又創建了一個列表對象[1,2,3,4,5],然後又將他和a相連接。

這種從變數到對象的連接,我們稱之為引用,以內存中的指針形式實現。因此直白的說,在內部,變數事實上是到對象內存空間的一個指針,而且指向的對象可以隨著程序賦值語句而不斷變化。

總結一下:變數名沒有類型,只有對象才有類型,變數只是引用了不同類型的對象而已。每一個對象都包含了兩個頭部信息,一個是類型標誌符,標識這個對象的類型,以及一個引用的計數器,用來表示這個對象被多少個變數名所引用,如果此時沒有變數引用他,那麼就可以回收這個對象。


type inference


舉個栗子,1+2和"1"+"2",python解釋器發現第二個公式加號左右兩邊有引號,因此會把它們當做string類型了,第一個公式木有引號,只有數值,因此當成int型了。


推薦閱讀:

如何使用pyinstaller打包python腳本?
python學習有必要了解底層嗎?
類可以是另一個類的對象嗎?
求問怎樣用python/python turtle畫「心」呢?

TAG:Python | 數據類型 | Python入門 |