python源碼分析----對象結構

來源:互聯網
上載者:User

標籤:

雖然自己會吐槽python這語言讓人受不了的慢,不過也不得不說python語言在文法上的精鍊,在寫代碼的時候確實會比java方便一些。。。不過由於python無法像java一樣項目的開始先定義一套強型別限制的介面,所以總感覺在寫python的時候有點不踏實。。。不過pycharm從某種程度上通過注釋也能減輕一點這方面的擔憂。。

好了。。。。。決定了要看一下python的實現。。。這裡就先從python的對象結構來說吧。。。。


在python中,所有的東西都是對象,整數是,方法也是,。。總之什麼都是。。。。

在看python的代碼實現中,可以隨處看到指標類型:PyObject*,那麼我們就先來看看PyObject這到底是怎麼定義的吧:

typedef struct _object {  //這個是所有python對象的基礎,這個是不可變對象    PyObject_HEAD} PyObject;

他就是整個python環境中最上層的對象結構,很簡單,就包括一個對象頭部,那麼來看看它的定義:

//通過這個結構,將所有對象構成一個雙鏈表/* Define pointers to support a doubly-linked list of all live heap objects. */#define _PyObject_HEAD_EXTRA                struct _object *_ob_next;               struct _object *_ob_prev;#define _PyObject_EXTRA_INIT 0, 0,#else#define _PyObject_HEAD_EXTRA#define _PyObject_EXTRA_INIT#endif//所有對象共有的資料,這個放在所有對象記憶體的最開始部分,首先是構成對象鏈表的前後執指標,其次是引用數量,以及它的類型對象/** (1)前後指標,構成迴圈鏈表 (2)引用計數 (3)類型對象**//* PyObject_HEAD defines the initial segment of every PyObject. */#define PyObject_HEAD                       _PyObject_HEAD_EXTRA                    Py_ssize_t ob_refcnt;                   struct _typeobject *ob_type;


可以看出,頭部由3部分來構成,首先是一個前後指標,用於將對象構成一個雙向的鏈表,其次就是比較重要的引用計數了。。。然後還有就是類型對象----》每一個對象都有一個指標指向其所指向的類型對象。。。


既然看到了引用計數,那麼就來說說python的GC吧。。。它跟java在GC最大的不同點就是有一套基於引用計數的記憶體回收。。。

(1)每一個對象都關聯一個引用計數,當這個計數為0的時候,那麼它的記憶體就可以被回收了

(2)對於有循環參考的情況,python也有一套可達性分析的gc來回收記憶體。。當然它這部分就比java簡單的多了


上面看的時最基礎的PyObject結構。。。另外這裡還有另外一種結構:PyVarObject,它用於指代一些變長對象,主要是一些容器。。。。

//一般都是一些容器啥的typedef struct {        //可變對象的基礎    PyObject_VAR_HEAD} PyVarObject; //即使是可變對象,首先也是有一個統一的對象頭部,ob_size一般用於記錄容器中資料項目個數,注意這裡不是位元組數#define PyObject_VAR_HEAD                   PyObject_HEAD                           Py_ssize_t ob_size; /* Number of items in variable part */#define Py_INVALID_SIZE (Py_ssize_t)-1

它其實也就是擴充了一個0b_size欄位。。。本質上也是與PyObject統一的。。。。所以對於PyVarObject,也可以用PyObject指標來引用。。從而達到了統一。。。。


通過上面的內容,我們知道,所有的對象,都會有一個ob_type指標域,用於指向當前對象的類型對象,那麼接下來來看看類型對象的定義:

//這個用來指定一個對象的類型對象typedef struct _typeobject {    PyObject_VAR_HEAD       //這裡有一個變長對象頭部    const char *tp_name; /* For printing, in format "<module>.<name>" */  //用於列印當前類型的資訊    Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */   //用於分配的大小    /* Methods to implement standard operations */    //下面是標準方法的定義    destructor tp_dealloc;    //析構當前對象    printfunc tp_print;       //在調用print列印類型的時候,將會調用這裡來進行輸出    getattrfunc tp_getattr;   //getter函數    setattrfunc tp_setattr;   //setter函數    cmpfunc tp_compare;       //比較函數    reprfunc tp_repr;         //轉化為字串    /* Method suites for standard classes */    PyNumberMethods *tp_as_number;      //最為數位進行操作的函數    PySequenceMethods *tp_as_sequence;  //作為序列進行操作的函數    PyMappingMethods *tp_as_mapping;    //作為字典進行操作的函數    /* More standard operations (here for binary compatibility) */    hashfunc tp_hash;                   //擷取hash值的函數    ternaryfunc tp_call;                //作為方法進行調用的時候    reprfunc tp_str;    getattrofunc tp_getattro;    setattrofunc tp_setattro;    /* Functions to access object as input/output buffer */    PyBufferProcs *tp_as_buffer;       //將當前對象作為buffer進行處理的時候的方法    /* Flags to define presence of optional/expanded features */    long tp_flags;    const char *tp_doc; /* Documentation string */   //當前類型的文檔    /* Assigned meaning in release 2.0 */    /* call function for all accessible objects */    traverseproc tp_traverse;    /* delete references to contained objects */    inquiry tp_clear;                                /* Assigned meaning in release 2.1 */    /* rich comparisons */    richcmpfunc tp_richcompare;    /* weak reference enabler */    Py_ssize_t tp_weaklistoffset;    /* Added in release 2.2 */    /* Iterators */    getiterfunc tp_iter;    iternextfunc tp_iternext;    /* Attribute descriptor and subclassing stuff */    struct PyMethodDef *tp_methods;          //方法    struct PyMemberDef *tp_members;          //成員屬性    struct PyGetSetDef *tp_getset;    struct _typeobject *tp_base;             //父類型    PyObject *tp_dict;    descrgetfunc tp_descr_get;    descrsetfunc tp_descr_set;    Py_ssize_t tp_dictoffset;    initproc tp_init;    allocfunc tp_alloc;    newfunc tp_new;    freefunc tp_free; /* Low-level free-memory routine */    inquiry tp_is_gc; /* For PyObject_IS_GC */    PyObject *tp_bases;    PyObject *tp_mro; /* method resolution order */    PyObject *tp_cache;    PyObject *tp_subclasses;    PyObject *tp_weaklist;    destructor tp_del;    /* Type attribute cache version tag. Added in version 2.6 */    unsigned int tp_version_tag;#ifdef COUNT_ALLOCS    /* these must be last and never 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;

可以看到,這裡主要是定義了很多公用的函數。。。。同時這裡可以看到最開始他也定義了一個變長對象的頭部PyObject_VAR_HEAD


那麼也就是說,類型對象本身也是一個對象,也可以用PyObject指標來引用。。。。


嗯。。那麼。。這裡問題就來了。。。。既然類型對象也是一個對象。。。。那麼類型對象他自己的類型對象是啥呢。。。?

嗯。。。在python中定義了一個最頂層的類型對象。。。。。

//最頂層的類型對象,它進行一個類型對象的自引用PyTypeObject PyType_Type = {    PyVarObject_HEAD_INIT(&PyType_Type, 0)    "type",                                     /* tp_name */    sizeof(PyHeapTypeObject),                   /* tp_basicsize */    sizeof(PyMemberDef),                        /* tp_itemsize */    (destructor)type_dealloc,                   /* tp_dealloc */    0,                                          /* tp_print */    0,                                          /* tp_getattr */    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 */    (ternaryfunc)type_call,                     /* tp_call */    0,                                          /* tp_str */    (getattrofunc)type_getattro,                /* tp_getattro */    (setattrofunc)type_setattro,                /* tp_setattro */    0,                                          /* tp_as_buffer */    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS,         /* tp_flags */    type_doc,                                   /* tp_doc */    (traverseproc)type_traverse,                /* tp_traverse */    (inquiry)type_clear,                        /* tp_clear */    type_richcompare,                                           /* tp_richcompare */    offsetof(PyTypeObject, tp_weaklist),        /* tp_weaklistoffset */    0,                                          /* tp_iter */    0,                                          /* tp_iternext */    type_methods,                               /* tp_methods */    type_members,                               /* tp_members */    type_getsets,                               /* tp_getset */    0,                                          /* tp_base */    0,                                          /* tp_dict */    0,                                          /* tp_descr_get */    0,                                          /* tp_descr_set */    offsetof(PyTypeObject, tp_dict),            /* tp_dictoffset */    type_init,                                  /* tp_init */    0,                                          /* tp_alloc */    type_new,                                   /* tp_new */    PyObject_GC_Del,                            /* tp_free */    (inquiry)type_is_gc,                        /* tp_is_gc */};

這裡可以看到它的類型對象本身引用了自己。。。。。

以後可以看到,所有的python類型對象都將它自己的類型對象指向了PyType_Type


好了。。基本上比較粗略的瞭解了python的對象結構。。。。。

python源碼分析----對象結構

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.