當前位置:編程學習大全網 - 源碼下載 - python定義模型

python定義模型

學python的人都知道,python中壹切皆是對象,如class生成的對象是對象,class本身也是對象,int是對象,str是對象,dict是對象...。所以,我很好奇,python是怎樣實現這些對象的?帶著這份好奇,我決定去看看python的源碼,畢竟源碼才是滿足自己好奇心最直接的方法。

在object.h文件中,定義了兩種數據結構PyObject和PyVarObject,代碼如下:

1 #define PyObject_HEAD \ 2 Py_ssize_t ob_refcnt; ? \ 3 struct _typeobject *ob_type; 4 ?5 #define PyObject_VAR_HEAD ? \ 6 PyObject_HEAD ? \ 7 Py_ssize_t ob_size; 8 ?9 typedef struct _object {10 PyObject_HEAD11 } PyObject;12 13 typedef struct {14 PyObject_VAR_HEAD15 } PyVarObject;

這兩種數據結構分別對應python的兩種對象:固定長度對象和可變長度對象。python中的所有對象都屬於這兩種對象中的壹種,如int,float是固定長度對象,list,str,dict是可變長度對象。從上面兩種對象數據結構定義來看,可變長度對象和固定長度對象的頭都是PyObject結構體,也就是說python中所有對象的開頭都包含這個結構體,並且可以用PyObject *指針來訪問任何對象,這種訪問對象的方法在python的源碼中隨處可見。PyObject結構體包含兩個成員,ob_refcnt和ob_type指針。ob_refcnt用來表示對象被引用的次數,當ob_refcnt == 0時,這個對象會被立即銷毀;ob_type指針指向了壹個_typeobject類型的結構體,表示對象所屬的類型,也就是生成該對象的類型,這其實很類似於面向對象中類與實例的關系,PyObject是某個類的實例,ob_type表示這個類。但與面向對象不同的是,ob_type本身也是個對象,我們來看下_typeobject的定義:

1 typedef struct _typeobject { 2 PyObject_VAR_HEAD 3 const char *tp_name; /*類型名 */ 4 Py_ssize_t tp_basicsize, tp_itemsize; /* 實例化對象的大小 */ 5 ?6 /* 標準方法 */ 7 ?8 destructor tp_dealloc; 9 printfunc tp_print;10 getattrfunc tp_getattr;11 setattrfunc tp_setattr;12 cmpfunc tp_compare;13 reprfunc tp_repr;14 15 /* 標準類(數值類,列表類,dict類)方法*/16 17 PyNumberMethods *tp_as_number;18 PySequenceMethods *tp_as_sequence;19 PyMappingMethods *tp_as_mapping;20 21 /* 其它標準方法*/22 23 hashfunc tp_hash;24 ternaryfunc tp_call;25 reprfunc tp_str;26 getattrofunc tp_getattro;27 setattrofunc tp_setattro;28 ... ?

29 } PyTypeObject;

從上面定義來看,_typeobject的開頭也包含了PyObject結構體,所以它也是壹個對象,既然它也是壹個對象,那麽按照面向對象的理解,它又是誰來生成的呢?答案是所有PyTypeObject對象都是通過PyType_Type來生成的,包括PyType_Type本身,因為PyType_Type也是PyTypeObject對象,有點繞。PyType_Type的定義是通過將PyType_Type聲明為全局靜態變量實現的,具體如下:

1 PyTypeObject PyType_Type = { 2 PyVarObject_HEAD_INIT(&PyType_Type, 0) 3 "type", /* tp_name */ 4 sizeof(PyHeapTypeObject), ? /* tp_basicsize */ 5 sizeof(PyMemberDef), /* tp_itemsize */ 6 (destructor)type_dealloc, ? /* tp_dealloc */ 7 0, ?/* tp_print */ 8 0, ?/* tp_getattr */ 9 0, ?/* tp_setattr */10 0, ?/* tp_compare */11 (reprfunc)type_repr, /* tp_repr */12 0, ?/* tp_as_number */13 0, ?/* tp_as_sequence */14 0, ?/* tp_as_mapping */15 (hashfunc)_Py_HashPointer, ?/* tp_hash */16 (ternaryfunc)type_call, /* tp_call */17 0, ?/* tp_str */18 (getattrofunc)type_getattro, /* tp_getattro */19 (setattrofunc)type_setattro, /* tp_setattro */20 0, ?/* tp_as_buffer */21 ...22 }

從PyType_Type定義來看,ob_type被初始化為它自己的地址,所以PyType_Type的類型就是自己。從python源碼實現來看,所有PyTypeObject的ob_type都會指向PyType_Type對象,所以PyType_Type是所有類型的類型,稱之為元類。python中定義了很多內建的類型對象,如PyInt_Type (int類型),PyStr_Type (str類型),PyDict_Type(dict類型) 類型對象,下面看下PyInt_Type類型的定義:

1 PyTypeObject PyInt_Type = { 2 PyVarObject_HEAD_INIT(&PyType_Type, 0) 3 "int", 4 sizeof(PyIntObject), 5 0, 6 (destructor)int_dealloc, /* tp_dealloc */ 7 (printfunc)int_print, ? /* tp_print */ 8 0, ?/* tp_getattr */ 9 0, ?/* tp_setattr */10 (cmpfunc)int_compare, ? /* tp_compare */11 (reprfunc)int_to_decimal_string, /* tp_repr */12 &int_as_number, /* tp_as_number */13 0, ?/* tp_as_sequence */14 0, ?/* tp_as_mapping */15 (hashfunc)int_hash, /* tp_hash */16 0, ?/* tp_call */17 ...18 };

從PyInt_Type定義來看,它主要包含了int數據類型相關的方法。PyInt_Type?類型對象的初始化和PyType_Type?類型類似,PyInt_Type類型的定義也是通過全局靜態變量的方式實現的,除了PyInt_Type了下,所有python內建類型都是以這種方式定義的。這些類型產生的對象都會***享這些類型對象,包括這些類型定義的方法。

在python中,怎樣查看對象的類型呢?有兩種方法,壹種是直接type:

1 >>> x = 12 >>> type(x)3 <type 'int'>

另壹種是通過對象的__class__屬性:

1 >>> x = 12 >>> type(x)3 <type 'int'>4 >>> x.__class__5 <type 'int'>

現在來看看int,str,dict這些類型的類型:1 <type 'int'>2 >>> type(int)3 <type 'type'>4 >>> type(str)5 <type 'type'>6 >>> type(dict)7 <type 'type'>8 >>> type(type)9 <type 'type'>  從這個輸出來看,int,str,dict這些類型的類型都是type,這也印證了前面說的,所有類型都是通過元類type生成的。

  • 上一篇:給文件加殼,加花,去殼,分別是什麽意思?
  • 下一篇:開發親友計算器邏輯思考過程
  • copyright 2024編程學習大全網