Before discussing the creation and behavior of objects, let’s first take a look at type objects. Python is a weakly typed language, but it does not mean that Python does not have types. There is a special object for processing object types in Python, which we call type objects. , if you don’t know the type of the object, you cannot open up memory space for the object, because the size of the memory occupied is the meta-information of the object and the basic information of the object. This is closely related to the type of the object. Therefore, it must appear where the python object is. For the corresponding type object, open the object.h file in the include folder in the python source code and view the source code of PyTypeObject. At approximately line 324:
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;
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;
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 */
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 de scriptor 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;
P y_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;
The above code is very long, with more than 100 lines for a structure, but the information contained is mainly divided into the following four categories:
1. Type name, tp_name, mainly used internally in python and during debugging, to identify the ownership of the object Type;
2. tp_basicsize and tp_itemsize, information on the size of the memory space allocated for creating this type of object;
3. Operation information associated with this type of object, such as tp_base and other pointers to functions;
4. Type information of type objects .
Key points 1. Creation of objects:
There are two main ways to create objects in Python, Python C API and PyInt_Type.
Python C API allows users to interact with Python from the C environment. There are two APIs, one is AOL (Abstract Object Layer), which is a generic API, and the other is COL (Concrete Object Layer), which is a type API; AOL has both The form of PyObject_*** can be applied to any Python object. The expression is generally expressed as: PyObject* intObj = PyObject_new(PyObject,&PyInt_Type), and the API of COL is generally as follows: PyObject* intObj = PyInt_FromLong (1000); we will Created a 1000 integer object.
No matter which Python C API is used, Python will eventually allocate memory directly, because these are all Python’s built-in objects, and if we define a class ourselves such as: class MySelf (object), Python will not Use the API to create, but Python will create an instance object through the type object corresponding to MySelf. The type object of MySelf is object, so Python will create the instantiation object of MySelf through object. We execute the following code:
class A(object):
pass
a = A()
type(a)
A.__base__
The result is as follows:
In fact, Python first instantiates object and runs the constructor method of object, and then instantiates A. This is closely related to the underlying implementation of Python. Any user-defined Python class ultimately has a common parent class object. When instantiating, the object class is instantiated first, and then downwards until the user-defined class is instantiated.
Screen Shot 2014-06-14 at 12.01.15
Object behavior:
There are three very important groups of operation families in the object's operation information, tp_as_number, tp_as_sequence, tp_as_mapping, which point to the PyNumberMethods, PySequenceMethods, and PyMappingMethods function families respectively. . For an object, he can define all operations in three function families at the same time, that is, the object can show the characteristics of numerical objects and the characteristics of associated objects. The code is as follows:
class MyInt(int):
def __getitem__(self , Key): t Return Key+Str (SELF)
A = MyINT (1)
B = MyINT (2)
Print A+B
Print A ['Key'] 3
key1
Finally let’s talk about the type of type object. The type of object is also an object, so what is the type of this object? First of all, it can be determined that he is also an object. We call them types of types. This is very, very, very, very much important. It is the PyType_Type structure in the source code. This is in the typeobject.c file in the objects folder. The source code is as follows:
PyTypeObject PyType_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
" type", / /* 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 */
(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 */
};
呵呵,这个看起来很复杂,PyInt_Type和PyType_Type之间如何联系起来的?就是前面博客中所说的引用计数器,一个整数对象运行时如下图所示:
Screen Shot 2014-06-14 at 下午1.32.09