日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 新闻分析系统 源码_python 源码分析之类型系统

發布時間:2025/3/15 python 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 新闻分析系统 源码_python 源码分析之类型系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

版權聲明:本文系原創,轉發請注明出處,商業用途聯系作者https://blog.csdn.net/wenxueliu/article/details/80919892

類型系統

一般對象是不能靜態分配的,而 python 所有內建對象都是靜態分配的

typedef struct _object {

_PyObject_HEAD_EXTRA

Py_ssize_t ob_refcnt;

struct _typeobject *ob_type;

} PyObject;

#ifdef Py_TRACE_REFS

/* 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

默認編譯 Py_TRACE_REFS 沒有定義,因此,實際為

//固定長度,如 int

typedef struct _object {

Py_ssize_t ob_refcnt; //很明顯引用計數器

struct _typeobject *ob_type; //保存類型信息

} PyObject;

//可變長對象,如 string, list

typedef struct {

PyObject ob_base;

Py_ssize_t ob_size; //元素個數

} PyVarObject;

python 所有對象的頭部都是 PyObject,因此,可以通過 PyObject 指針指向任何對象。

我們最熟悉的 list 的定義如下:

#define PyObject_VAR_HEAD PyVarObject ob_base;

typedef struct {

PyObject_VAR_HEAD

/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */

PyObject **ob_item;

/* ob_item contains space for 'allocated' elements. The number

* currently in use is ob_size.

* Invariants:

* 0 <= ob_size <= allocated

* len(list) == ob_size

* ob_item == NULL implies ob_size == allocated == 0

* list.sort() temporarily sets allocated to -1 to detect mutations.

*

* Items must normally not be NULL, except during construction when

* the list is not yet visible outside the function that builds it.

*/

Py_ssize_t allocated;

} PyListObject;

據此,知道所有的對象都包含共同的 PyObject,不同對象之間的區別在哪里呢?

主要的區別在于不同的對象對應 C 中不同的結構體

typedef struct _typeobject {

PyObject_VAR_HEAD

const char *tp_name; /* For printing, in format "." */

Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */

/* Methods to implement standard operations */

destructor tp_dealloc;

printfunc tp_print;

getattrfunc tp_getattr;

setattrfunc tp_setattr;

PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)

or tp_reserved (Python 3) */

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;

ternaryfunc tp_call;

reprfunc tp_str;

getattrofunc tp_getattro;

setattrofunc tp_setattro;

/* Functions to access object as input/output buffer */

PyBufferProcs *tp_as_buffer;

/* Flags to define presence of optional/expanded features */

unsigned 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;

/* 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;

destructor tp_finalize;

#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;

其中

tp_bases : 指向基類指針

tp_basicsize : 分配對象空間大小

tp_new : 創建對象時調用對應的函數

創建對象

tp_new 根據 tp_basicsize 分配內存

如果 tp_new 為 NULL,會向上找到到 tp_base

初始化

tp_init

對象創建

Python C API

分配 Py[type]_Type 對象

AOL(abstract Object Layer) : 形如 PyObject_*** 可以應用到任何 python 對象上,如 PyObject_New 來創建對象

COL(Concrete Object Layer) : 只作用某一類型對象,如 PyInt_FromLong(10)

>>> __builtins__.__dict__['int']

>>> a = int(10)

>>> a

10

>>> type(a)

>>> int.__base__

類型

PyTypeObject PyBaseObject_Type = {

PyVarObject_HEAD_INIT(&PyType_Type, 0)

"object", /* tp_name */

sizeof(PyObject), /* tp_basicsize */ 0, /* tp_itemsize */

object_dealloc, /* tp_dealloc */

0, /* tp_print */

0, /* tp_getattr */

0, /* tp_setattr */

0, /* tp_reserved */

object_repr, /* tp_repr */

0, /* tp_as_number */

0, /* tp_as_sequence */

0, /* tp_as_mapping */

(hashfunc)_Py_HashPointer, /* tp_hash */

0, /* tp_call */

object_str, /* tp_str */

PyObject_GenericGetAttr, /* tp_getattro */

PyObject_GenericSetAttr, /* tp_setattro */

0, /* tp_as_buffer */

Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */

PyDoc_STR("object()\n--\n\nThe most base type"), /* tp_doc */

0, /* tp_traverse */

0, /* tp_clear */

object_richcompare, /* tp_richcompare */

0, /* tp_weaklistoffset */

0, /* tp_iter */

0, /* tp_iternext */

object_methods, /* tp_methods */

0, /* tp_members */

object_getsets, /* tp_getset */

0, /* tp_base */

0, /* tp_dict */

0, /* tp_descr_get */

0, /* tp_descr_set */

0, /* tp_dictoffset */

object_init, /* tp_init */

PyType_GenericAlloc, /* tp_alloc */

object_new, /* tp_new */

PyObject_Del, /* tp_free */

};

我們在自定義類的時候,都會繼承 object 類,而這個類對應的

C 結構體就是 PyBaseObject_Type,從其 tp_name 為 "object" 可知端倪。

在創建對象的時候,所有對象都會調用這里的 object_new 函數

對象的行為

在 PyTypeObject 中三個成員決定對象的行為

PyNumberMethods *tp_as_number;

PySequenceMethods *tp_as_sequence;

PyMappingMethods *tp_as_mapping;

PyNumberMethods : 數字操作,加減乘除

PySequenceMethods : 序列相關

PyMappingMethods : 關聯對象

如果一個對象支持上述操作,對應的指針就不為 NULL。

對象類型

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_reserved */

(reprfunc)type_repr, /* tp_repr */

0, /* tp_as_number */

0, /* tp_as_sequence */

0, /* tp_as_mapping */

0, /* 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 */

0, /* 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 */

};

總結:

所有的對象都一個 PyObject 指針頭,而 PyObject 中包含 PyTypeObject

包含所有對象的基本信息

所有以 object 為基類的對象 : tp_base 指向 PyBaseObject_Type

所有對象類型: ob_type 指向 PyType_Type

PyBaseObject_Type 的 ob_type 也指向 PyType_Type

python 多態

所有對象都有一個頭 PyObject,而 PyObject 的 ob_type 指向 PyType_Type

所有對象的類型通過其 ob_type 指向的 PyType_Type 獲知其類型信息

PyObject* PyObject_Repr(PyObject *v) {

//...

res = (*v->ob_type->tp_repr)(v);

//...

}

不同類型的 v 的類型對應不同的 PyType_Type 對象,調用對應對象的

tp_repr 方法

引用計數

#define Py_INCREF(op) ( \

_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \

((PyObject *)(op))->ob_refcnt++)

#define Py_DECREF(op) \

do { \

PyObject *_py_decref_tmp = (PyObject *)(op); \

if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \

--(_py_decref_tmp)->ob_refcnt != 0) \

_Py_CHECK_REFCNT(_py_decref_tmp) \

else \

_Py_Dealloc(_py_decref_tmp); \

} while (0)

#define _Py_Dealloc(op) ( \

_Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \

(*Py_TYPE(op)->tp_dealloc)((PyObject *)(op)))

Py_INCREF : 增加計數

Py_DECREF : 減少計數,但對象 ob_refcnt 為 0 時調用 tp_dealloc 方法釋放內存

注:

python 中引用計數次數不超過 Py_ssize_t 指定的大小的限制

tp_dealloc 并不意味著會釋放內存,而是將其返回內存池

#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)

#define _Py_NewReference(op) ( \

_Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA \

_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \

Py_REFCNT(op) = 1)

可見在初始化的時候,將 ob_refcnt 置為 1

總結

以上是生活随笔為你收集整理的python 新闻分析系统 源码_python 源码分析之类型系统的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。