【Python】【一些概念与对比】
type.__new__() : 返回类。可以把类看作是metaclass 创建出来的实例
普通类里的__new__() : 返回类的实例。
__new__() : 返回类的实例。Python解释器自动执行的。
__init__() : 得先有实例,才可以调用这个方法。
type.__new__(cls,name,bases,attrs) : cls->类,name-> 类名, bases->继承的类组成的一个元祖 , attrs-> 类的成员,包含成员变量和成员方法等。
type('Hello', (object,), dict(hello=fn)): 第一个参数:class名字, 第二个参数:继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法
第三个参数:class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上
参考:https://www.cnblogs.com/MY0213/p/8735440.html
object 和 type的关系很像鸡和蛋的关系,先有object还是先有type没法说,obejct和type是共生的关系,必须同时出现的。
在看下去之前,也要请先明白,在Python里面,所有的东西都是对象的概念。
在面向对象体系里面,存在两种关系:
- 父子关系,即继承关系,表现为子类继承于父类,如『蛇』类继承自『爬行动物』类,我们说『蛇是一种爬行动物』,英文说『snake is a kind of reptile』。在python里要查看一个类型的父类,使用它的__bases__属性可以查看。
- 类型实例关系,表现为某个类型的实例化,例如『萌萌是一条蛇』,英文说『萌萌 is an instance of snake』。在python里要查看一个实例的类型,使用它的__class__属性可以查看,或者使用type()函数查看。
这两种关系使用下面这张图简单示意,继承关系使用实线从子到父连接,类型实例关系使用虚线从实例到类型连接:

我们将使用一块白板来描述一下Python里面对象的关系,白板划分成三列:

先来看看type和object:
>>> object
<type 'object'>
>>> type
<type 'type'>
它们都是type的一个实例,表示它们都是类型对象。
在Python的世界中,object是父子关系的顶端,所有的数据类型的父类都是它;type是类型实例关系的顶端,所有对象都是它的实例的。它们两个的关系可以这样描述:
- object是一个type,object is and instance of type。即Object是type的一个实例。
>>> object.__class__
<type 'type'>
>>> object.__bases__ # object 无父类,因为它是链条顶端。
()
- type是一种object, type is kind of object。即Type是object的子类。
>>> type.__bases__
(<type 'object'>,)
>>> type.__class__ # type的类型是自己
<type 'type'>
此时,白板上对象的关系如下图:

我们再引入list, dict, tuple 这些内置数据类型来看看:
>>> list.__bases__
(<type 'object'>,)
>>> list.__class__
<type 'type'>
>>> dict.__bases__
(<type 'object'>,)
>>> dict.__class__
<type 'type'>
>>> tuple.__class__
<type 'type'>
>>> tuple.__bases__
(<type 'object'>,)
它们的父类都是object,类型都是type。
再实例化一个list看看:
>>> mylist = [1,2,3]
>>> mylist.__class__
<type 'list'>
>>> mylist.__bases__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__bases__'
实例化的list的类型是<type 'list'>, 而没有了父类。
把它们加到白板上去:

虚线是跨列产生关系,而实线只能在一列内产生关系。除了type和object两者外。
当我们自己去定个一个类及实例化它的时候,和上面的对象们又是什么关系呢?试一下:
>>> class C(object):
... pass
...
>>> C.__class__
<type 'type'>
>>> C.__bases__
(<type 'object'>,)
实例化
>>> c = C()
>>> c.__class__
<class '__main__.C'>
>>> c.__bases__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute '__bases__'
这个实例化的C类对象也是没有父类的属性的。
再更新一下白板:

白板上的第二列,它们既是第三列的类型,又是第一列的实例,我们把这列的对象叫TypeObject。
白板上的第三列,它们是第二列类型的实例,而没有父类(__bases__)的,我们把它们叫Instance。
你以为事情就这样完了?不。。看见type孤零零在第一列其实不是那么舒服。。我们给它整几个玩伴看看。但要怎么整呢?要属于第一列的,必须是type的子类,那么我们只需要继承type来定义类就可以了:
>>> class M(type):
... pass
...
>>> M.__class__
<type 'type'>
>>> M.__bases__
(<type 'type'>,)
>>>
嗯嗯,M类的类型和父类都是type。这个时候,我们可以把它归到第一列去。那么,要怎么样实例化M类型呢?实例化后它应该出现在那个列?嗯嗯,好吧,刚才你一不小心创建了一个元类,MetaClass!即类的类。如果你要实例化一个元类,那还是得定义一个类:
>>> class TM(object):
... __metaclass__ = M # 这样来指定元类。
...
...
>>> TM.__class__
<class '__main__.M'> # 这个类不再是type类型,而是M类型的。
>>> TM.__bases__
(<type 'object'>,)
好了,现在TM这个类就是出现在第二列的。
再总结一下:
第一列,元类列,type是所有元类的父亲。我们可以通过继承type来创建元类。
第二列,TypeObject列,也称类列,object是所有类的父亲,大部份我们直接使用的数据类型都存在这个列的。
第三列,实例列,实例是对象关系链的末端,不能再被子类化和实例化。
为什么要有两个,而不是一个。
如果type和object只保留一个,那么一定是object。只有object 时,第一列将不复存在,只剩下二三列,第二列表示类型,第三列表示实例,这个和大部分静态语言的类型架构类似,如java 。
这样的架构将让python 失去一种很重要的动态特性--动态创建类型。本来,类(第二列的同学)在Python里面是一个对象(typeobject),对象是可以在运行时动态修改的,所以我们能在你定义一个类之后去修改他的行为或属性!拿掉第一列后,第二列变成了纯类型,写成怎样的,运行时行为就怎样。在这一点上,并不比静态语言有优势。
所以,以上!
【Python】【一些概念与对比】的更多相关文章
- Python 简明教程 --- 3,Python 基础概念
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 控制复杂性是计算机编程的本质. -- Brian Kernighan 了解了如何编写第一个Pytho ...
- [python01] python列表,元组对比Erlang的区别总结
数据结构是通过某种方式组织在一起的数据元素的集合,这些数据元素可以是数字,字符,甚至可以是其他的数据结构. python最基本的数据结构是sequence(序列):6种内建的序列:列表,元组,字符串, ...
- 图片哈希概论及python中如何实现对比两张相似的图片
Google 以图搜图的原理,其中的获取图片 hash 值的方法就是 AHash. 每张图片都可以通过某种算法得到一个 hash 值,称为图片指纹,两张指纹相近的图片可以认为是相似图片. 以图搜图的原 ...
- Python六大开源框架对比:Web2py略胜一筹
Python是一门动态.面向对象语言.其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性.除了语言本身的设计目的之外,Python标准库也是值得大家称赞的,Python甚至还自带 ...
- DHCP和NAT的概念与对比
转自:http://network.51cto.com/art/201009/223440.htm 在网络协议中,DHCP和NAT的使用非常普遍.那么对于这两个协议你是否有所掌握呢?这里我们针对这两方 ...
- web编程速度大比拼(nodejs go python)(非专业对比)
C10K问题的解决,涌现出一大批新框架,或者新语言,那么问题来了:到底谁最快呢?非专业程序猿来个非专业对比. 比较程序:输出Hello World! 测试程序:siege –c 100 –r 100 ...
- python——几种截图对比方式!
本次记录的几种截图对比方式,主要是为了在进行手机自动化测试时,通过截图对比来判断测试的正确性,方式如下: # -*- coding: utf- -*- ''' 用途:利用python实现多种方法来实现 ...
- 理解Python闭包概念
闭包并不只是一个python中的概念,在函数式编程语言中应用较为广泛.理解python中的闭包一方面是能够正确的使用闭包,另一方面可以好好体会和思考闭包的设计思想. 1.概念介绍 首先看一下维基上对闭 ...
- python基础概念(转)
基础回顾: 1.集合 集合有2个重要作用:关系测试(并集,差集,交集)和去重. 2.文件编码 2.7上默认文件编码是ASCII码,因为不支持中文,就出了GB2312,在2.7上要支持中文就必须申明文件 ...
随机推荐
- Android4.0 主线程不能访问网络异常解决办法
从两个方面说下这个问题: 1. 不让访问网络的原因 2. 解决该问题的办法 不让访问网络的原因: 由于对于网络状况的不可预见性,很有可能在网络访问的时候造成阻塞,那么这样一来我们的主线程UI线程 就会 ...
- eval & sleep
ltp-ddt can_loopback source 'functions.sh'; interface='can0'; bitrate=; do_cmd "do_can_loopback ...
- JDBC和servlet设计思路、DAO模式思路、MVC思路粗略总结
#JDBC和Servlet联合起来使用的项目思路: 说明:建库,最好一开始设置utf8字符集 step1: 在数据库中建表 如 create table t_user{ ...... } step ...
- thinkphp 检测验证码
/** * 检测验证码 * @param integer $id 验证码ID * @return boolean 检测结果 */function check_verify($code, $id = 1 ...
- Python建立多线程任务并获取每个线程返回值
1.进程和线程 (1)进程是一个执行中的程序.每个进程都拥有自己的地址空间.内存.数据栈以及其他用于跟踪执行的辅助数据.进程也可以派生新的进程来执行其他任务,不过每个新进程都拥有自己的内存和数据栈,所 ...
- Golang对文件读写操作
package main import ( "bufio" "fmt" "io" "os" ) //写 func Wri ...
- Solr基本操作
/update 使用/update进行索引维护,进入Solr管理界面SolrCore下的Document下: 我们进行更新操作可以用json和xml多种格式,这里以xml格式为例说明.先来看看界面上的 ...
- 从percona server 5.7换到mariadb 10.2
过去两年半一直推荐使用percona server,今天开始,因为一些mysql迟迟不不愿意支持的特性,打算换回mariadb 10.2了,具体哪些不说了,总之非常关键,mariadb都支持一两年了, ...
- shell &&,||,()
做个笔记. 1. linux命令返回值介绍 shell 在执行某个命令时,会有一个返回值,该值保存在shell变量$?中.当$?为0时,表示命令执行成功:当$?为1时,表示命令执行失败. 2. &am ...
- vue2.0之element table的使用
说明: 1.改变表头居中问题: 需要在el-table-column中添加 header-align="center" <el-table :data="t ...