【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上要支持中文就必须申明文件 ...
随机推荐
- golang学习笔记12 beego table name `xxx` repeat register, must be unique 错误问题
golang学习笔记12 beego table name `xxx` repeat register, must be unique 错误问题 今天测试了重新建一个项目生成新的表,然后复制到旧的项目 ...
- Git在Eclipse中的使用
一.把远程仓库的项目clone到eclipse里面: 最新版的Eclipse上已经集成了Git插件.所以在Eclipse中可以很方便的使用Git的功能. 在使用Git功能之前,需要先进行下简单的设置. ...
- flask框架----基于flask的扩展实现的简单的页面登录
废话不多说,直接上代码 from flask import Flask,render_template,request,redirect,session app = Flask(__name__,te ...
- Java五大框架
2017-6-13 Lifusen 此文章仅代表个人观点,如有问题提出请联系Q:570429601 1.Hibernate (开放源代码的对象关系映射框架) Hibernate是一个开放源代码的对象关 ...
- QQ项目
QQ第一部分: 1.数据库 每一个QQ账户必须有 a. state:是否上线的状态 b. IP:正在上线的主机的IP c. port:UDP端口号(用这个和别的好友通讯) 注:TCP连接时,在 ...
- Java中的ASCII码与Unicode码
先上代码 后续更新 public class Unicode { public static void main(String[] args) { char ch1 = 'c'; char ch2 = ...
- linux普通用户提权
tar通配符注入. echo 'echo "chenglee ALL=(root) NOPASSWD: ALL" > /etc/sudoers' > demo.sh e ...
- 使用SimpleDateFormat时的日期和时间模式
日期和时间模式 日期和时间格式由日期和时间模式 字符串指定.在日期和时间模式字符串中,未加引号的字母 ‘A’ 到’Z’ 和’a’ 到’z’ 被解释为模式字母,用来表示日期或时间字符串元素.文本可以使用 ...
- Git学习笔记---安装与初始化 连接远程版本库
1.Git的安装 sudo apt-get install git 用的是linux(ubuntu)系统,安装非常简单,上面一条命令就够了. 2.初次运行的配置 Git 提供了一个叫做 git con ...
- Convert DataFrame string complex i to j python // “Cloning” row or column vectors
https://stackoverflow.com/questions/30808286/convert-dataframe-string-complex-i-to-j-python https:// ...