按照python中"一切皆对象的原理",所有创建的对象,都是一个已知存在的class实例化的结果;那么class又是被哪个"类"实例化的呢?先看下面的一段代码

class Foo(object):
pass obj = Foo()
print type(obj)
print type(Foo) 结果为:
<class '__main__.Foo'>
<type 'type'>

可以看到:obj是由Foo实例化,而Foo由type类创建

这样Foo就可以这样实现了,看下面:

def func(self):
print "charles" Foo = type('Foo',(object,),{'func':func})
print Foo
f = Foo()
f.func() 结果为:
<class '__main__.Foo'>
charles

那么问题随之产生了,既然class是由type实例化而来的,那么type中是如何实现类的创建的呢?

实际上,在被type实例化的类中,有一个__metaclass__字段,指明由谁来实例化得到该类

class MyType(type):

    def __init__(self, what, bases=None, dict=None):
print "333"
super(MyType, self).__init__(what, bases, dict) def __call__(self, *args, **kwargs):
print "444"
obj = self.__new__(self, *args, **kwargs) self.__init__(obj) class Foo(object): __metaclass__ = MyType def __init__(self):
print '222' def __new__(cls, *args, **kwargs):
print '1111'
return object.__new__(cls, *args, **kwargs) obj = Foo() 结果为:
333
444
1111
222

可以看到Mytype和Foo都存在__new__()方法,那么这个方法是干什么的呢?

__new__()函数:

看下面:

class A(object):
def __init__(self):
print 'init' def __new__(cls, *args, **kwargs):
print "first"
print object.__new__(cls,*args,**kwargs)
A() 结果:
first
<__main__.A object at 0x0000000002730EB8>

可以看到__new__方法比__init__方法先执行,object.__new__(cls,*args,**kwargs)为A的实例化的对象,如果我打印self的话

class A(object):
def __init__(self):
print self,'----'
print 'init' def __new__(cls, *args, **kwargs):
print "first"
print object.__new__(cls,*args,**kwargs)
return object.__new__(cls,*args,**kwargs)
A() 结果为:
first
<__main__.A object at 0x000000000260BE10>
<__main__.A object at 0x000000000260BE10> ----
init

可以看到self的值,正好是__new__返回的结果;

观察__new__返回的对象,参数中包含cls,表示当前的类,如果传入的不是当前的类(即使是父类),__init__不会被调用:

class B(object):
pass
class A(B):
def __init__(self):
print self,'----'
print 'init' def __new__(cls, *args, **kwargs):
print "first"
return object.__new__(B,*args,**kwargs)
A() 结果为:
first
<__main__.A object at 0x000000000238BEB8>

  

结论:1、python的类的实例,是__new__方法创建的

2、__new__方法必须有一个cls参数,表示当前类,只有传入的是当前cls,__init__才会被调用

3、类的实例self,就是__new__方法return  object.__new__(cls,*args,**kwargs)的结果;

参考:http://www.cnblogs.com/tuzkee/p/3540293.html

http://www.cnblogs.com/wupeiqi/p/4766801.html

  

python类和对象的底层实现的更多相关文章

  1. 一文讲全了Python 类和对象内容

    摘要:这是一个关于 Python 类和对象的全部内容. 本文分享自华为云社区<从零开始学python | Python 类和对象-面向对象编程>,原文作者:Yuchuan  . Pytho ...

  2. python类与对象各个算数运算魔法方法总结

    1.python类与对象各个算术运算魔法方法总结: 2.各个魔法方法应用举例: 3.实例训练: (1)我们都知道在 Python 中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常 ...

  3. python 类和对象的属性

    python类和对象的属性分为类属性和对象属性两大类,类属性属于类,而对象属性属于对象. 1. 父类的对象属性会被子类的对象继承. 2. 父类的类属性会被子类继承,还是作为类属性,如果父类改变了类属性 ...

  4. python类、对象

    python类.对象 学习完本篇,你将会深入掌握 什么是类,对象 了解类和对象之间的关系 能独立创建一个People(人类),属性有姓名.性别.年龄.提供一个有参的构造方法,编写一个show方法,输出 ...

  5. python 类、对象、方法、属性

    在python中,一个对象的特征也称为属性(attribute).它所具有的行为也称为方法(method) 结论:对象=属性+方法 在python中,把具有相同属性和方法的对象归为一个类(class) ...

  6. python类、对象、方法、属性之类与对象笔记

    python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性(特征)和行为来描述一个对象的.比如家里的小狗, ...

  7. python类与对象基本语法

    面向对象编程的2个非常重要的概念:类和对象. 对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念--类. 类就相当于制造飞机时的图纸,用它 ...

  8. python 类和对象

    类和对象 类 1.类的组成    数据和函数,二者是类的属性 2.两个作用: 实例化 属性引用  属性引用:类名.属性(增删改查)   实例化: 类名加括号就是实例化,会自动出发__init__的运行 ...

  9. Python类和对象

    目录 类与对象 其他方法 继承 经典类和新式类 派生 组合 接口.归一化设计与抽象类 继承实现的原理 子类中调用父类的方法 指名道姓 super()方法 多态与多态性 封装 单下划线开头 双下划线开头 ...

随机推荐

  1. 有关Set集合的一个小问题

    先看两段代码: Demo1: Set<Short>s=new HashSet<>(); for(Short i=0;i<100;i++){ s.add(i); s.rem ...

  2. Windows 2016 无域故障转移群集部署方法 超详细图文教程 (一)

    故障转移群集是一个很实用的功能,而windows在2016版本开始,终于支持不用域做故障转移群集. 在群集中,我们可以设定一个"群集IP" 而客户端只需要根据这个"群集I ...

  3. jquery鼠标放上去显示悬浮层即弹出定位的div层

    <div><a id="a1" onmouseover="javascript:show('a1','div1');" onmouseout= ...

  4. vue2.0 slot用法

    学习vue.js也有一段时间了,关于slot这一块,也看了不少次了,总感觉有点迷迷糊糊,不知其然也不知其所以然,抽出一段完整的时间,再一次仔细学习.稍微有点理解了,在此稍作记录,好记性不如烂笔头嘛! ...

  5. linux系统 python升级创建虚拟环境

    Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替之前的virtualenv. 该venv模块提供了创建轻量级“虚拟环境”,提供与系统Python的隔离支持.每一个虚拟环境都有其自 ...

  6. android 开发 实现一个自定义布局的AlertDialog对话框

    对话框有很多实现方法,最常见的是在一个点击事件中代码直接写出对话框.如下: package com.example.lenovo.mydemo2; import android.content.Dia ...

  7. 非阻塞套接字编程, IO多路复用(epoll)

    非阻塞套接字编程: server端 import socket server = socket.socket() server.setblocking(False) server.bind(('', ...

  8. 查询oracle约束所关联的表

    ORA-02292: 违反完整约束条件 (ADMIN.FK_PROJECTP_RELATIONS_OFFICIAL) - 已找到子记录 遇到这样的错误,熟悉的话可能从约束名称看出是那张表的约束,因为名 ...

  9. windows服务器自动删除日志文件

    https://blog.csdn.net/u010050174/article/details/72510367 步骤: 1.新建 一个bat脚本 2.添加到window执行计划中,进行每日执行. ...

  10. linux常用命令以及快捷键

    find命令查找某些文件并将其拷贝到指定目录 [root@host lib]# find -name "*hbase*.jar" |xargs -i cp {}  /root/aa ...