首頁  >  文章  >  後端開發  >  python源碼學習 之 物件創建與物件的行為

python源碼學習 之 物件創建與物件的行為

巴扎黑
巴扎黑原創
2016-12-07 11:24:371234瀏覽

在將對象的創建和行為之前,我們先來看一下類型對象,python是弱類型語言,但並不代表python沒有類型,python中處理對象的類型有一個專門的對象,我們稱之為類型對象,如果不知道對象的類型就無法為對象開闢內存空間,因為佔用內存的大小是對象的元信息,是對象的基本信息,這與對象所屬類型密切相關,因此,他一定回出現在python對象所對應的類型物件中,開啟python原始碼中的include資料夾的object.h文件,檢視PyTypeObject的來源碼,在大約第324行: 


typedef struct _typeobject { 
 , in format "." */ 
    Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ 

   
    printfunc tp_print; 
    getattrfunc tp_getattr;
    setattrfunc tp_setattr; 
    cmpfunc tp_compare; 
    reprfunc tp_repr; 

  as_number; 
    PySequenceMethods *tp_as_sequence; 
    PyMappingMethods *tp_as_mapping; 

    /* More standard operations (here for  ary compatibility) */ 

    hashfunc tp_hash; 
    ternaryfunc tp_call; 
    reprfunc tp_str _setattro; 

    /* Functions to access object as input/output buffer */ 
    PyBufferProcs *tp_as_buffer 
🜎 to define presence of optional/expanded features */ 
    long tp_flags; 

    const char *tp_doc   /* call function for all accessible objects */ 
traverseproc tp_traverse; 

    /* delete references to contained objects */ 
    inquiry tp_clear; 

   arisons */ 
    richcmpfunc tp_richcompare; 

    /* weak reference enabler */ 
Py_ssize_t tp_weaklistoffset; 

    /* Added in release 2.2 */ 
    /* Iterators */  
    /* Attribute descriptor and subclassing stuff */ 
    struct PyMethodDef *tp_methods; 
    struct PyMemberDef *tp_members;
    struct PyGetSetDef *tp_getset; 
    struct _typeobject *tp_base; 
    PyObject *tp_dict; 
_cr ; 
    Py_ssize_t tp_dictoffset; 
    initproc tp_init; 
    allocfunc tp_alloc; 
/tp 是; 
    PyObject *tp_subclasses; 
    PyObject *tp_weaklist; 
    destructor tp_del; 

    /* 類型 attribute cache version tag. Added in version 2.6 */ 
    unsigned int tp_version_tag; explicitly initialized */ 
    Py_ssize_t tp_allocs; 
    Py_ssize_t tp_frees; 
Py_ssize_t tp_maxalloc; 
    struct _typeobject *tp_prev; 
    struct _typeobject *tp_next; 
#endif 
} PyTypeObject;上面這段程式碼很長,一個結構體100多行,不過所包含的資訊主要分為如下四大類: 
1、型別名,tp_name,主要是python內部以及調試時使用,用來識別對象的所屬類型; 
2、tp_basicsize和tp_itemsize,建立該類別物件分配記憶體空間的大小的資訊; 
3、與該類別物件關聯的操作訊息,例如說tp_base等指向函數的指標; 
4、類型物件的類型資訊。 

重點1、物件的建立: 
python建立物件主要有兩種方法,Python C API和PyInt_Type。
Python C API讓使用者從C環境與Python交互,一共有兩種API,一種是AOL(Abstract Object Layer)即泛型API,另一種是COL(Concrete Object Layer)即類型API;AOL都有PyObject_***的形式,可以應用在任何Python物件上,表達式一般表示為:PyObject* intObj = PyObject_new(PyObject,&PyInt_Type),而COL的API一般如下:PyObject* intObj = PyInt_FromLong(1000);我們就創建了一個1000整數物件。
無論採用哪種Python C API,Python都是最終直接分配內存,因為這都是Python的內建對象,而如果我們自己定義了一個類別如:class MySelf(object),對於類型MySelf,Python不會使用API​​來創建,但Python會透過MySelf所對應的類型物件來建立實例對象, MySelf的類型物件是object,所有Python都會透過object來建立MySelf的實例化物件。我們執行以下程式碼: 

class A(object): 
    pass 
a = A() 
type(a) 
A.__base__ 
結果
實際上,Python是先實例化object運行object的建構方法,然後再實例化A,這與Python的底層實現有著密切的聯繫。任何一個使用者自訂的Python類,最後都有一個共同的父類object,實例化時先實例化object類,一次向下,直到實例化使用者自訂的類別。
Screen Shot 2014-06-14 at 下午12.01.15 

物件的行為: 
在物件的操作資訊中有三組非常重要的操作族,tp_as_number,tp_as_sequence,tp_as_ocpingytpPestm,PMapPencePotPentft 。對於一個對象,他可以同時定義三個函數族中的所有操作,即對象可以表現出數值對象的特性和關聯對象的特性,代碼如下: 


class MyInt(int): 
    def __getitem__(self ,key): 
        return key+str(self) 
a = MyInt(1) 
b = MyInt(2) 
print a+b 
print a['key'] 3 
key1 
最後說一下類型物件的類型。對象的型別也是一個對象,那麼這個對象的型別又是什麼呢?首先可以確定他也是一個對象。我們稱之為類型的類型。這個十分、非常、非常、very much重要,就是原始碼中的PyType_Type結構體,這個在objects資料夾的typeobject.c檔案裡,原始碼如下: 

PyTypeObject PyType_Type = {  type",                                     /* tp_name */ 
    sizeof(PyHeapTypeObject),                   /* tp_basicsize */ 
    sizeof(PyMemberDef),                        /* tp_itemsize */ 
    (destructor)type_dealloc,                   /* tp_dealloc */ 
    0,                                          /* tp_print */ 
0,                                        0,                                          /* tp_setattr */ 
    0,                                  /* tp_compare */ 
    (reprfunc) type_repr,                       /* tp_repr */ 
    0,                                      /* tp_as_number */ 
    0,                                          /* tp_as_sequence */ 
    0,                                          /* tp_as_mapping */
    (hashfunc)_Py_HashPointer,                 /* tp_hash */        /* tp_call */ 
    0,                   */ 
    (getattrofunc)type_getattro,              /* tp_getattro */ 
  tp _塞塔特羅*/ 
    0,                             Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 
        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS,         /* tp_flags */ 
    type_doc,                              /* tp_doc */ 
    (traverseproc)type_traverse,                /* t verse */ 
   (查詢)type_clear,                        /* tp_clear */ 
    type_richcompare,                                          /* tp_richcompare */ 
   偏移量(PyTypeObject , tp_weaklist),        /* tp_weaklistoffset */ 
    0,                                     /* tp_iter */ 
    0,                                          /* tp_iternext */ 
    type_methods,                                             /* tp_members */ 
    type_getsets,        getset */ 
    0,                                                                                             /* tp_descr_get */ 
    /* tp_descr_get */ 
     0, /* tp_descr_set */ 
    offsetof(PyTypeObject, tp_dict),           /* tp_dic                             /* tp_alloc */ 
    type_new,             
    PyObject_GC_Del,                           
   (查詢)type_is_gc,                       /* tp_is_gc */ 
}; 
呵呵,這個看起來很複雜,PyInt_Type 和PyType_Type 之間是如何聯繫起來的? 1.32 .09 

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:python原始類下一篇:python原始類