Python实例一个类背后发生了什么


Posted in Python onFebruary 09, 2016

首先来看一个例子,正常情况下我们定义并且实例一个类如下

class Foo(object):
 
  def __init__(self):
    pass
 
obj = Foo()  # obj是通过Foo类实例化的对象

上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。

print type(obj) # 输出: Foo 表示,obj 对象由Foo类创建
print type(Foo) # 输出:type表示,Foo类对象由 type 类创建
如果按照一切事物都是对象的理论:对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

一、两个基本的类
这里和有必要提到一下在Python中有两个最基本的对象,<type ‘object'> 和 <type ‘type'>,这两个对象是所有对象的起源。

1、<type ‘type'>的类型是<type ‘type'>(它本身),<type ‘type'>的父类是<type ‘object'>
2、<type ‘object'>的类型是<type ‘type'>,<type ‘object'>没有父类
在Python对象系统中,<type ‘object'>和<type ‘type'>的关系就像鸡和蛋的关系,不能说谁先于(创建)谁,两者是相互依赖的,共同构成了Python对象系统的基础.有点难理解,不过没有关系,知道有种这么两个东西就好了,比较我们也不是设计Python的人,没有必要搞的那么清楚.

二、类的创建
主要有两种方式,不过本质上都是一样的,都是通过type类来实例一个用户类

//普通方式
  class Foo(object):
   
  def func(self):
  print 'hello wupeiqi'

//特殊方式(type类的构造函数)
  def func(self):
    print 'hello wupeiqi'
  
  Foo = type('Foo',(object,), {'func': func})
 #type第一个参数:类名
 #type第三个参数:类的成员

由上面可以看出来 , Foo类是由type类实例而来,那么具体的创建的过程是怎么样的呢,接着往下面看:

来了解几个概念
new __init()__metaclass__:

  • __new__函数是实例一个类所要调用的函数,每当我们调用obj = Foo()来实例一个类时,都是先调用__new__()
  • 然后再调用__init__()函数初始化实例. __init__()在__new__()执行后执行,
  • 类中还有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

三、阐述运行过程

1、mytype产生一个叫做Foo的实例,主要的原理就是设置了,__metaclass__=MyTypoe,这样就指定mytype类来实例foo类,如果Python没有找到__metaclass__,它会继续在(父类)中寻找 __metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。
2、mytype类中的__new__方法返回了一个对象,所有的Python实例都是这句代码创建的type.__new__(cls,name,bases,attrs)
3、mytype的__init__()函数初始化Foo类,在这里我们可以和在__new__()函数一样设置Foo类的attr属性,比如类中的方法,字段属性等
4、和Foo类的创建过程一样,studen类继承了Foo类,所以重复123步骤,得到一个studen类
5、当用户使用Foo()或者studen()来实例类时,会默认调用类中的_new_()方法,要是之类里面没有这个方法就到父类里面寻找__new__(),我们可以充分利用这个new函数,比如来实现Python中的单例模式,或者对类成员进行批量的修改等等.
6、产生了一个实例后马上执行__init__()函数,进行初始化实例,
7、由上面的运行结果可以看出,其中Foo和studen类的类型是<class '__main__.MyType'>,这也证明了Foo类和studen类都是由MyType实例而来…而第三个例子,可以看出Foo2类的类型是<type 'type'>,这个并不例外,Foo2继承了object类,(这个,还是跳过吧,前面已经讲过type和object相爱相杀的关系了)
总结
首先,你知道了类其实是能够创建出类实例的对象。好吧,事实上,类本身也是实例,当然,它们是元类的实例。Python中的一切都是对象,它们要么是类的实例,要么是元类的实例,除了type。type实际上是它自己的元类,在纯Python环境中这可不是你能够做到的,这是通过在实现层面耍一些小手段做到的。其次,元类是很复杂的。对于非常简单的类,你可能不希望通过使用元类来对类做修改。你可以通过其他两种技术来修改类:

1、Monkey patching
2、class decora

以上就是本文的详细内容,希望对大家的学习有所帮助。

Python 相关文章推荐
用Python输出一个杨辉三角的例子
Jun 13 Python
python中执行shell命令的几个方法小结
Sep 18 Python
python中 logging的使用详解
Oct 25 Python
python3+mysql查询数据并通过邮件群发excel附件
Feb 24 Python
Python Selenium 之关闭窗口close与quit的方法
Feb 13 Python
Django异步任务之Celery的基本使用
Mar 23 Python
Python3.6+Django2.0以上 xadmin站点的配置和使用教程图解
Jun 04 Python
Python多叉树的构造及取出节点数据(treelib)的方法
Aug 09 Python
TensorFlow实现批量归一化操作的示例
Apr 22 Python
Python实现密钥密码(加解密)实例详解
Apr 26 Python
Python venv虚拟环境配置过程解析
Jul 08 Python
Python实现拼音转换
Jun 07 Python
Python中的条件判断语句基础学习教程
Feb 07 #Python
Python模拟登录验证码(代码简单)
Feb 06 #Python
Python上传package到Pypi(代码简单)
Feb 06 #Python
深入讲解Java编程中类的生命周期
Feb 05 #Python
python&amp;MongoDB爬取图书馆借阅记录
Feb 05 #Python
Python中常用操作字符串的函数与方法总结
Feb 04 #Python
Python中的字符串类型基本知识学习教程
Feb 04 #Python
You might like
我的php学习笔记(毕业设计)
2012/02/21 PHP
采集邮箱的php代码(抓取网页中的邮箱地址)
2012/07/17 PHP
ThinkPHP中关联查询实例
2014/12/02 PHP
smarty模板引擎基础知识入门
2015/03/30 PHP
列举PHP的Yii 2框架的开发优势
2015/07/03 PHP
基于JQuery的多标签实现代码
2012/09/19 Javascript
jQuery.fn和jQuery.prototype区别介绍
2013/10/05 Javascript
js使用正则实现ReplaceAll全部替换的方法
2014/08/22 Javascript
javascript实现随时变化着的背景颜色
2015/04/02 Javascript
判断js的Array和Object的实现方法
2016/08/29 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
2017/03/31 Javascript
VUE前端cookie简单操作
2017/10/17 Javascript
Vue中使用的EventBus有生命周期
2018/07/12 Javascript
微信小程序自定义组件之可清除的input组件
2018/07/17 Javascript
详解vue 2.6 中 slot 的新用法
2019/07/09 Javascript
原生js代码能实现call和bind吗
2019/07/31 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
2019/08/02 jQuery
layui前端时间戳转化实例
2019/11/15 Javascript
js判断非127开头的IP地址的实例代码
2020/01/05 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
python3实现域名查询和whois查询功能
2018/06/21 Python
django中使用Celery 布式任务队列过程详解
2019/07/29 Python
浅析Python数字类型和字符串类型的内置方法
2019/12/22 Python
Pycharm激活方法及详细教程(详细且实用)
2020/05/12 Python
python装饰器实现对异常代码出现进行自动监控的实现方法
2020/09/15 Python
俄罗斯宠物用品网上商店:ZooMag
2019/12/12 全球购物
世界上最大的铁人三项商店:Tri UK
2020/11/04 全球购物
行政人事经理职位说明书
2014/03/05 职场文书
2014学雷锋活动心得体会
2014/03/10 职场文书
道德演讲稿
2014/05/21 职场文书
财务个人年度总结范文
2015/02/26 职场文书
2015年语文教研组工作总结
2015/05/23 职场文书
律师催款函范文
2015/06/24 职场文书
四年级作文之植物
2019/09/20 职场文书
基于Golang 高并发问题的解决方案
2021/05/08 Golang
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android