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通过解析网页实现看报程序的方法
Aug 04 Python
Python实现约瑟夫环问题的方法
May 03 Python
python中异常报错处理方法汇总
Nov 20 Python
深入理解Django自定义信号(signals)
Oct 15 Python
在Python中Dataframe通过print输出多行时显示省略号的实例
Dec 22 Python
Python实现Linux监控的方法
May 16 Python
django框架防止XSS注入的方法分析
Jun 21 Python
Django对接支付宝实现支付宝充值金币功能示例
Dec 17 Python
python中图像通道分离与合并实例
Jan 17 Python
Python warning警告出现的原因及忽略方法
Jan 31 Python
Python多个装饰器的调用顺序实例解析
May 22 Python
Python实现猜拳与猜数字游戏的方法详解
Apr 06 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
第十五节--Zend引擎的发展
2006/11/16 PHP
APACHE的AcceptPathInfo指令使用介绍
2013/01/18 PHP
计算php页面运行时间的函数介绍
2013/07/01 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
Microsoft Ajax Minifier 压缩javascript的方法
2010/03/05 Javascript
jquery blockUI 遮罩不能消失与不能提交的解决方法
2011/09/17 Javascript
JS操作Cookies包括(读取添加与删除)
2012/12/26 Javascript
解析使用JS 清空File控件的路径值
2013/07/08 Javascript
jQuery 1.9.1源码分析系列(十三)之位置大小操作
2015/12/02 Javascript
最简单纯JavaScript实现Tab标签页切换的方式(推荐)
2016/07/25 Javascript
JavaScript如何实现跨域请求
2016/08/05 Javascript
jQuery实现带延时功能的水平多级菜单效果【附demo源码下载】
2016/09/21 Javascript
BootStrap 图片样式、辅助类样式和CSS组件的实例详解
2017/01/20 Javascript
BootStrap Datepicker 插件修改为默认中文的实现方法
2017/02/10 Javascript
JavaScript Canvas绘制圆形时钟效果
2020/08/20 Javascript
微信小程序与php 实现微信支付的简单实例
2017/06/23 Javascript
小程序开发中如何使用async-await并封装公共异步请求的方法
2019/01/20 Javascript
[03:34]2014DOTA2西雅图国际邀请赛 淘汰赛7月15日TOPPLAY
2014/07/15 DOTA
Python 调用DLL操作抄表机
2009/01/12 Python
Python 异常处理的实例详解
2017/09/11 Python
快速了解Python相对导入
2018/01/12 Python
python和shell获取文本内容的方法
2018/06/05 Python
python3中os.path模块下常用的用法总结【推荐】
2018/09/16 Python
使用memory_profiler监测python代码运行时内存消耗方法
2018/12/03 Python
Windows平台Python编程必会模块之pywin32介绍
2019/10/01 Python
python随机数分布random均匀分布实例
2019/11/27 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
HTML5之消息通知的使用(Web Notification)
2018/10/30 HTML / CSS
澳大利亚家庭花园和DIY工具网店:VidaXL
2019/05/03 全球购物
英国网上电器商店:Electricshop
2020/03/15 全球购物
小学教师自我鉴定
2013/11/07 职场文书
店长岗位的工作内容
2013/11/12 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
运动会开幕词
2015/01/28 职场文书
2016年党员承诺书范文
2016/03/24 职场文书
springboot用户数据修改的详细实现
2022/04/06 Java/Android