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

歡迎訪問 生活随笔!

生活随笔

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

python

在python中、处理的一切都是对象_Python 3+ 一切都是对象

發布時間:2024/9/15 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在python中、处理的一切都是对象_Python 3+ 一切都是对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于 Python 來說,一切都是對象 。 這句話很重要,當你對某個特性不了解時,回想下這句話也許就能想通

一個整數一個對象,一個浮點數也是一個對象,一個函數也是一個對象

>>> isinstance(3,object)

True

>>> isinstance(3.14, object)

True

>>> isinstance(max,object)

True

既然一切都是對象,那么這一切應該都有一個類來創建。它們都有一個公共的基礎類,這個基礎類就是 object

一切都是對象

object

如果我們使用 type() 函數來檢查下它們的類型,就會發現

>>> type(1)

>>> type(1)

>>> type(3.14)

>>> type(max)

那么 int 、float 和 builtin_function_or_method 又是什么呢?

>>> type(int)

>>> type(int)

>>> type(float)

>>> type(builtin_function_or_method)

Traceback (most recent call last):

File "", line 1, in

NameError: name 'builtin_function_or_method' is not defined

但,其實,object 也是一個對象

>>> type(object)

type()

看到這里,想必對 type 這個類型很好奇,到底是什么鬼?

一探究竟的事情,我們等下再說,我們先來了解下 type() 函數的原理

type() 函數是一個內建可調用類,只有一個參數的情況下,它的作用相當于訪問參數的 __class__ 屬性

>>> type(int)

>>> int.__class__

更有意思的是,type(type) 的結果還算是

>>> type(type)

>>> type.__class__

什么意思,也就是自己創建了自己? 這....

越挖越深,算了,以后有篇幅再來講解 type()

我們先挖一下源碼,因為 type() 、int 、float 都說是內建函數,所以我們找到內建函數的源碼

在 Python 目錄下的 bltinmodule.c 文件中的第 2892 行開始

SETBUILTIN("None", Py_None);

SETBUILTIN("Ellipsis", Py_Ellipsis);

SETBUILTIN("NotImplemented", Py_NotImplemented);

SETBUILTIN("False", Py_False);

SETBUILTIN("True", Py_True);

SETBUILTIN("bool", &PyBool_Type);

SETBUILTIN("memoryview", &PyMemoryView_Type);

SETBUILTIN("bytearray", &PyByteArray_Type);

SETBUILTIN("bytes", &PyBytes_Type);

SETBUILTIN("classmethod", &PyClassMethod_Type);

SETBUILTIN("complex", &PyComplex_Type);

SETBUILTIN("dict", &PyDict_Type);

SETBUILTIN("enumerate", &PyEnum_Type);

SETBUILTIN("filter", &PyFilter_Type);

SETBUILTIN("float", &PyFloat_Type);

SETBUILTIN("frozenset", &PyFrozenSet_Type);

SETBUILTIN("property", &PyProperty_Type);

SETBUILTIN("int", &PyLong_Type);

SETBUILTIN("list", &PyList_Type);

SETBUILTIN("map", &PyMap_Type);

SETBUILTIN("object", &PyBaseObject_Type);

SETBUILTIN("range", &PyRange_Type);

SETBUILTIN("reversed", &PyReversed_Type);

SETBUILTIN("set", &PySet_Type);

SETBUILTIN("slice", &PySlice_Type);

SETBUILTIN("staticmethod", &PyStaticMethod_Type);

SETBUILTIN("str", &PyUnicode_Type);

SETBUILTIN("super", &PySuper_Type);

SETBUILTIN("tuple", &PyTuple_Type);

SETBUILTIN("type", &PyType_Type);

SETBUILTIN("zip", &PyZip_Type);

可以看到

int 是一個對 PyLong_Type 的引用

float 是一個對 PyFloat_Type 的引用

object 是一個對 PyBaseObject_Type 的引用

type 是一個對 PyType_Type 的引用

繼續追查,我們可以看到如下定義

Include/longobject.h

PyAPI_DATA(PyTypeObject) PyLong_Type;

Include/floatobject.h

PyAPI_DATA(PyTypeObject) PyFloat_Type;

Include/object.h

PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */

PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */

PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */

所以,接下來我們就想知道 PyAPI_DATA 是什么鬼,這個在 pyport.h 中定義

#ifndef PyAPI_DATA

# define PyAPI_DATA(RTYPE) extern RTYPE

#endif

也就是說,經過預處理之后,它們就是下面這樣

PyTypeObject PyLong_Type;

PyTypeObject PyFloat_Type

PyTypeObject PyType_Type;

PyTypeObject PyBaseObject_Type;

PyTypeObject PySuper_Type;

是什么意思呢? 它們都是 PyTypeObject 結構體的一個變量,所以它們的終極類型,結果都是 type

因為它們都是函數,這些函數都會傳入一個字面量,然后返回一個對應類型的實例

所以,我們就要知道 PyTypeObject 到底是什么

#ifdef Py_LIMITED_API

typedef struct _typeobject PyTypeObject; /* opaque */

#else

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;

#endif

結構體成員很多,我們只要記住第二個結構體成員 tp_name 就好,它表示當前的對象的類型

比如 PyLongType 在初始化的時候是這樣的

Objects/longobject.c

PyTypeObject PyLong_Type = {

PyVarObject_HEAD_INIT(&PyType_Type, 0)

"int", /* tp_name */

offsetof(PyLongObject, ob_digit), /* tp_basicsize */

sizeof(digit), /* tp_itemsize */

long_dealloc, /* tp_dealloc */

0, /* tp_print */

0, /* tp_getattr */

0, /* tp_setattr */

0, /* tp_reserved */

long_to_decimal_string, /* tp_repr */

&long_as_number, /* tp_as_number */

0, /* tp_as_sequence */

0, /* tp_as_mapping */

(hashfunc)long_hash, /* tp_hash */

0, /* tp_call */

long_to_decimal_string, /* tp_str */

PyObject_GenericGetAttr, /* tp_getattro */

0, /* tp_setattro */

0, /* tp_as_buffer */

Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |

Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */

long_doc, /* tp_doc */

0, /* tp_traverse */

0, /* tp_clear */

long_richcompare, /* tp_richcompare */

0, /* tp_weaklistoffset */

0, /* tp_iter */

0, /* tp_iternext */

long_methods, /* tp_methods */

0, /* tp_members */

long_getset, /* tp_getset */

0, /* tp_base */

0, /* tp_dict */

0, /* tp_descr_get */

0, /* tp_descr_set */

0, /* tp_dictoffset */

0, /* tp_init */

0, /* tp_alloc */

long_new, /* tp_new */

PyObject_Del, /* tp_free */

};

可以看到第二個參數 tp_name 就被設置為 "int"

同樣的,我們可以看到 PyBaseObject_Type 變量的初始化為

typeobject.c

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

};

tp_name 成員變量被設置為 object

同時在 typeobject.c 中還可以看到 PyType_Type 變量的初始化

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

};

到此為止,我們已經了解了每隔類型的內建函數 int() 、float() 的創建過程,也知道了 type() 函數第一次的返回值

PyObject_VAR_HEAD

接下來我們所要了解的是,為什么

>>> type(int)

>>> type(object)

>>> type(type)

這就涉及到 type() 函數的實現了,我們知道,PyType_Type 、PyBaseObject_Type 和 PyLong_Type 都是的成員變量 tp_base 都是 0 ,也就是說它們都沒有基類

但是大家有沒有發現另一個有趣的成員變量,就是 PyObject_VAR_HEAD

可以說,幾乎所有的類型都有這個成員變量,它,就是繼承鏈條,它用于表示當前類型在所有繼承體系中的為止

我們來看看它的實現

Include/object.h

#define PyObject_VAR_HEAD PyVarObject ob_base;

而這個成員變量的初始化方式都是

PyVarObject_HEAD_INIT(&PyType_Type, 0)

也就是說,PyObject_VAR_HEAD 實際上是 PyVarObject 的一個實例

那 PyVarObject 又是什么呢?

typedef struct {

PyObject ob_base;

Py_ssize_t ob_size; /* Number of items in variable part */

} PyVarObject;

PyVarObject 包含了一個 PyObject 的實例,那么 PyObject 又是什么呢?

typedef struct _object {

_PyObject_HEAD_EXTRA

Py_ssize_t ob_refcnt;

struct _typeobject *ob_type;

} PyObject;

看到這,是不是很明朗了,struct _typeobject 就是 PyTypeObject

而 _PyObject_HEAD_EXTRA 的實現如下

#define _PyObject_HEAD_EXTRA \

struct _object *_ob_next; \

struct _object *_ob_prev;

所以,這條繼承鏈就很清楚了,也能理解為什么 type(int)==type(type) 了

Python 中所有的對象,都是由此而成,可能你很費解,那么 int 和 object 其實沒有任何的,對吧,我們再下一章節再來學習

總結

以上是生活随笔為你收集整理的在python中、处理的一切都是对象_Python 3+ 一切都是对象的全部內容,希望文章能夠幫你解決所遇到的問題。

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