(明天论文就要送审了!!!距离毕业一个月!!!)

  现在还记得刚开始学python时候被这种动态语言惊到的那种感觉,列表和字典对象可以随意伸缩,简直不能更帅了,但是一直不知道内部到底是怎么实现的,python源码用C实现的,但是C是过程性语言啊。

  说怎么实现之前,先捋捋什么是对象,对这个我觉得《python源码剖析》这本书里面的解释很有意思:“一个对象实际上就是一片被分配的内存空间,这些内存可能是连续的,也可能是不连续的,这都不重要,重要的是这片内存在更高的层次上可以作为一个整体来考虑,这个整体就是对象,在这片内存中,存储着一系列的数据以及可以对这些数据进行修改和读取操作的代码”,一个很有意思的角度。

  一个对象被创建后,它所占用的内存大小就是不可变的了,这意味着对可变长度的数据来说(比如字符串),只能在对象内部维护一个指向可变大小内存区域的指针。

  在python中,一切皆是对象,其中所有对象的核心就是一个叫PyObject的结构体

 typedef struct _object{
int ob_refcnt;
struct _typeobject *ob_type;
}PyObject;

  其中,ob_refcnt为引用计数,_typeobject决定了对象的类型,ob_type指向了一个类型对象(我的理解:基类),这个结构体将出现在所有对象所占有内存的最开始的地方,就比如在一个int类中:

 typedef struct{
PyObject _HEAD;
long ob_ival;
}PyIntObject;

int值得信息就保存在ob_ival中,这是python2.5中的int对象,如果是list这种可变长度的对象,这种方法显然是不行的,那么就把头部结构体PyObject中加一个表示此对象占有多少个对象的信息ob_size,这个值也就表明了边长对象中一共有多少个元素:

 #define PyObject_VAR_HEAD
PyObject_HEAD
int ob_size; typedef struct{
PyObject_VAR_HEAD
}PyVarObject;

所以,python中对象的内存表示是下面这个样子的:

从上面可以看到,对象的类型完全由ob_type指向的类型对象决定的,那么类型对象是什么鬼?

typedef struct _typedefobject{
PyObject_VAR_HEAD
char*tp_name;
int tp_basicsize,tp_itemsize;
destructor tp_dealloc;
printfunc tp_print;
hashfunc tp_hash;
ternaryfunc tp_call;
/*……*/
}PyTypeObject;

*tp_basicsize,tp_itemsize指定了分配内存空间的大小

*其余的带有func字眼的指向函数的指针表明了这个对象携带的操作

那么,对象是怎么创建的?

首先要说明在python新式类中,所有的对象的基类都是object,就像java中所有对象的基类都是Object所构成的单根类体系一样,也就是说,所有的对象都会自动继承其基类的所有方法。

在需要创建一个对象的时候,比如创建int对象需要用到的PyInt_Type对象时候,先寻找PyInt_Type类中的tp_new指针,如果这个指针为null,就寻找其父类,比如object中的tp_new指针,用这个指针指向的函数来创建对象,它指向的函数会首先查看PyInt_Type中的tp_basicsize字段,根据这个字段的信息来决定为这个对象分配多少内存,当创建完成后,会在PyInt_Type中寻找tp_init,用其指向的函数来初始化tp_new分配的内存。我理解的是,tp_new就相当于python类中的__new__静态类方法,tp_init就相当于__init__方法。

可以看到,在PyTypeObject中有很多只想函数的指针,这些函数指针也就决定了对象的行为,其中有三个非常重要的函数指针指向三个操作族:

tp_as_number-------->PyNumberMethods

tp_as_sequence------>PySequenceMethods  (列表list)

tp_as_mapping------>PyMappingMethods    (字典dict)

对每一种对象来说,可以同时指向三种操作族,可以通过哪些钩子方法实现,比如__getitem__,__setitem__

参考资料:python源码剖析

[python]源码-对象的创建和行为的更多相关文章

  1. [python 源码]整数对象的创建和维护

    刚开始学python时候,发现一个很迷惑的现象,一直到看了源码后才知道了: >>> a=6 >>> b=6 >>> a is b True 想用同 ...

  2. [python 源码]字符串对象的实现

    还是带着问题上路吧,和整数对象的实现同样的问题: >>> a='abc' >>> b='abc' >>> a is b True >> ...

  3. Python 源码剖析(一)【python对象】

    处于研究python内存释放问题,在阅读部分python源码,顺便记录下所得.(基于<python源码剖析>(v2.4.1)与 python源码(v2.7.6)) 先列下总结:      ...

  4. Python源码剖析——01内建对象

    <Python源码剖析>笔记 第一章:对象初识 对象是Python中的核心概念,面向对象中的"类"和"对象"在Python中的概念都为对象,具体分为 ...

  5. Python源码中的PyCodeObject

    1.Python程序的执行过程 Python解释器(interpreter)在执行任何一个Python程序文件时,首先进行的动作都是先对文件中的Python源代码进行编译,编译的主要结果是产生的一组P ...

  6. python源码学习(一)——python的总体架构

    python源码学习(一)——python的总体架构 学习环境: 系统:ubuntu 12.04 STLpython版本:2.7既然要学习python的源码,首先我们要在电脑上安装python并且下载 ...

  7. Python源码分析(一)

    最近想学习下Python的源码,希望写个系列博客,记录的同时督促自己学习. Python源码目录 从Python.org中下载源代码压缩包并解压,我下载的是Python2.7.12,解压后: 对于主要 ...

  8. Python 源码剖析(六)【内存管理机制】

    六.内存管理机制 1.内存管理架构 2.小块空间的内存池 3.循环引用的垃圾收集 4.python中的垃圾收集 1.内存管理架构 Python内存管理机制有两套实现,由编译符号PYMALLOC_DEB ...

  9. Python 源码学习之内存管理 -- (转)

    Python 的内存管理架构(Objects/obmalloc.c): _____ ______ ______ ________ [ int ] [ dict ] [ list ] ... [ str ...

随机推荐

  1. Activity相关知识点总结

    一.Activity状态 Activity有三种状态:active/running.paused.stopped. 1.active/running状态,在当前屏幕时,即用户可见的Activity,位 ...

  2. Hibernate5笔记8--Hibernate事务相关内容

    Hibernate事务相关内容: (1) 事务四大特性(简称ACID): (1)原子性(Atomicity) 事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行. (2)一致性(Con ...

  3. 再战CS231-快速排序

    1.用python实现快速排序 print quicksort([3,6,8,10,1,2,1]) # Prints "[1, 1, 2, 3, 6, 8, 10]" ''' @a ...

  4. Android Build.VERSION.SDK_INT兼容介绍

    尽管Android向下兼容不好,但是一个程序还是可以在多个平台上跑的.向下兼容不好,接口改变,新的平台上不能用旧的API,旧的平台更不可能用新的API,不等于一个平台需要一个APK.可以在高SDK上开 ...

  5. TCP检验和

    TCP的检验和   检验和目的 目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动.如果接收方检测到检验和有差错,则TCP段会被直接丢弃. TCP在计算检验和时,要加上一个12字节的伪首 ...

  6. Apple Notification Center Service--ANCS【转】

    Apple Notification Center Service 转自:http://studentdeng.github.io/blog/2014/03/22/ancs/ MAR 22ND, 20 ...

  7. python操作mysql(pymysql + sqlalchemy)

    pymysql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同. 下载安装 pip3 install pymysql 使用操作 1.执行sql #!/usr/bi ...

  8. Linux下实现ping功能

    实现ping功能,就肯定要用到ping命令,那么在Linux下ping命令为: ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面&g ...

  9. Hexo命令无法找到 -问题修复

    本人PC安装hexo按照官方npm方式下载: npm install -g hexo-cli 但是到了控制台,输入hexo总是无法找到该命令,提示:Command not Found!!!,无论git ...

  10. jquery 绑定,mvc和webform的三种方式

    asp.net里的绑定方式,on的绑定方式无效 $('#SelCommandType').bind('click', function () { }); mvc里的绑定方式 $('#DownList' ...