[py]python中的特殊类class type和类的两面性图解
生活中的模具
生活中 | 编程 |
---|---|
万物都从无到有, 起于烟尘 | () |
生产原料,铁 | object |
车床-生产各类模具 | 元类即metaclass,对应python的class type |
模具-生产各类实在的物品,如饮水机桶子,月饼 | 'abc' [1,2,3],{} |
python中 object 和 type(生产模具的工具)的关系概述
object 和 type的关系很像鸡和蛋的关系,先有object还是先有type没法说,obejct和type是共生的关系,必须同时出现的。
在看下去之前,也要请先明白,在Python里面,所有的东西都是对象的概念。在面向对象体系里面,存在两种关系:
- 父子关系,即继承关系,表现为子类继承于父类,如『蛇』类继承自『爬行动物』类,我们说『蛇是一种爬行动物』,英文说『snake is a kind of reptile』。在python里要查看一个类型的父类,使用它的__bases__属性可以查看。
- 类型实例关系,表现为某个类型的实例化,例如『萌萌是一条蛇』,英文说『萌萌 is an instance of snake』。在python里要查看一个实例的类型,使用它的__class__属性可以查看,或者使用type()函数查看。
python的特殊类 class type , 类的两面性
python中class type是一个特殊的类, 他的实例是一种类, 他的产物有两面性,
站在class type角度讲, 他的实例有class str,class dict等,也就是class str, class dict是实例.
站在class str,class dict角度讲,他们是类, 可以创造各自的实例.
所有的class都继承自class object, class object的父类是().
class type的父类是class object: () --> class object --> class type
自定义类继承示例: () --> class object --> class B --> class A
认识2个函数
python中对象间无非两种关系
关系 | 检测函数 | 描述 |
---|---|---|
继承关系 | bases 我的父类是谁 | snake is a kind of reptile |
实例关系 | class 或type() 我是哪个类的实例 | 萌萌 is an instance of snake |
判断所有类属于type类
使用__class__可以判断实例(类)属于哪个类
使用type() 也可以判断实例(类)属于哪个类
- 判断class type属于type类
>>> type #查看值
>>> <class 'type'>
>>> type(type)
<class 'type'>
>>> type.__class__
<class 'type'>
- 判断class object属于type类
>>> object #查看值
>>> <class 'object'>
>>> object.__class__
<class 'type'>
>>> type(object)
<class 'type'>
- 判断class str属于type类
>>> str.__class__
<class 'type'>
>>> type(str)
<class 'type'>
多层继承-type类的两面性
- 判断自定义类class A,属于type类
>>> class A:pass
>>> A.__class__
<class 'type'>
>>> type(A)
<class 'type'>
- 判断实例属于type类
>>> class A:pass
>>> class B(A):pass
>>> type(B)
<class 'type'>
__bases__
查找父类
__bases__方法可以查找本类的直接父类
- 检查A的父类
() --> class object --> class B --> class A
>>> class A:pass
>>> class B(A):pass
>>> B.__bases__
(<class '__main__.A'>,)
>>> A.__bases__
(<class 'object'>,)
>>> object.__bases__
()
实例没有父类AttributeError
>>> ''.__bases__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__bases__'
class type的父类是class object
() --> class object --> class type
>>> type.__bases__
(<class 'object'>,)
>>> object.__bases__
()
小结
1,python一切皆对象
1.1 一切都是对象
1.2 任何对象都是由对应的类创建出来的
那类型这种对象是由谁创建出来的呢?继续拿模具来说,生产模具的模具是谁呢?模具的模具:元类(metaclass)。
元类跟其它模具不同之处在于,它生产出来的是不是一般的对象,是模具。
元类除了能生产模具之外,跟其它模具相比无其它特别的地方。
1.2 所有对象都有三种特性: id、类型、值
id: id是一个对象的编号,每个对象天生都有一个与众不同的编号(目前实现是对象的地址).
id()
value: 值是对象的价值所在。各种各样的对象保存着各种各样的值,Python的世界才会如此多彩。
有的对象值永远不会变,叫不可变对象(immutable);
有的对象值可以变,叫可变对象(mutable)。
type: 类型就像是商品上印的生产厂商一样,标识自己被谁生产出来。每个对象天生都会有个铭牌,写着自己的类型。
在Python里,类(class)和型(type)指的是同一件东西。汉字真是精妙,类和型放在一块念是多么的自然。
type()
2,python面向对象体系里面存在两种关系:
继承关系 __bases__ 检测
类与实例关系 type __class__ 检测
3,[类与实例关系]class type是一种特殊的类,它的实例有两面性
站在class type角度讲, 他的实例有class str,class dict等,也就是class str, class dict是实例. 这些实例最高父类是object.
站在class str,class dict角度讲,他们是类, 可以创造各自的实例. 这些实例不存在父类的概念
4,[继承关系]
4.1class type的继承:
() --> class object --> class type
4.2自定义继承:
() --> class object --> class B --> class A
4.3普通实例不存在继承关系
type和object的关系
参考:
Python 的 type 和 object 之间是怎么一种关系?
Python中对象、类型、元类之间的关系
py3源码中的说法
/*
Objects are structures allocated on the heap. Special rules apply to
the use of objects to ensure they are properly garbage-collected.
Objects are never allocated statically or on the stack; they must be
accessed through special macros and functions only. (Type objects are
exceptions to the first rule; the standard types are represented by
statically initialized type objects, although work on type/class unification
for Python 2.2 made it possible to have heap-allocated type objects too).
An object has a 'reference count' that is increased or decreased when a
pointer to the object is copied or deleted; when the reference count
reaches zero there are no references to the object left and it can be
removed from the heap.
An object has a 'type' that determines what it represents and what kind
of data it contains. An object's type is fixed when it is created.
Types themselves are represented as objects; an object contains a
pointer to the corresponding type object. The type itself has a type
pointer pointing to the object representing the type 'type', which
contains a pointer to itself!).
Objects do not float around in memory; once allocated an object keeps
the same size and address. Objects that must hold variable-size data
can contain pointers to variable-size parts of the object. Not all
objects of the same type have the same size; but the size cannot change
after allocation. (These restrictions are made so a reference to an
object can be simply a pointer -- moving an object would require
updating all the pointers, and changing an object's size would require
moving it if there was another object right next to it.)
Objects are always accessed through pointers of the type 'PyObject *'.
The type 'PyObject' is a structure that only contains the reference count
and the type pointer. The actual memory allocated for an object
contains other data that can only be accessed after casting the pointer
to a pointer to a longer structure type. This longer type must start
with the reference count and type fields; the macro PyObject_HEAD should be
used for this (to accommodate for future changes). The implementation
of a particular object type can cast the object pointer to the proper
type and back.
A standard interface exists for objects that contain an array of items
whose size is determined when the object is allocated.
*/
Python3源码学习-对象
- 对象分配一般在堆上进行
- 每个对象有一个reference count 引用计数
- 每一个对象有一个type来真正表明对象类型
- 对象一旦分配,其在内存的地址就不在改变
- 任何对象可以通过PyObject *类型指针访问,PyObject结构只包含引用计数和type类型指针两个字段,实际的对象数据由type类型指针指向,即_typeobject结构体。
对象一般就是开辟在堆上的结构体;
一些特殊的规则运用在对象上,以保证他们被正确的GC;
对象永远不会静态开辟或者在栈上;
Python中的对象,主要分为一般对象和变长对象(list、dict之类),
一般的对象就是PyObject,然后变长对象其实就是给PyObject加了个size成为了PyVarObject。
对于所有对象来说,均有2个重要的元素:
1.引用计数(reference count),对象中的引用计数用来记录引用对象的数目,会在指针指向或删除对该对象的引用时,
相应的增加或者减少,当引用计数达到0,就代表这没有指针指向这个对象了,这个对象便会在堆中移除。
从名字就可以看出来,这个域是为了支持垃圾回收而定义的。
2.类型(type),对象的类型表示对象包含数据的类型,每个对象中都有一个指向类型的指针。
比较有意思的是,type也是一个对象,type对象的类型是它本身,所以type对象的类型指针就指向它自己了。
对于可变长的对象(比如list,dict),会多一个域:大小(size),这个大小表示这个变长变量中元素的个数。
注意,是元素的个数,不是字节个数。
另外头部还有_PyObject_HEAD_EXTRA,这个宏定义了next和prev指针,用来支持用一个双链表把所有堆中的对象串起来。
[py]python中的特殊类class type和类的两面性图解的更多相关文章
- 全面理解Python中的类型提示(Type Hints)
众所周知,Python 是动态类型语言,运行时不需要指定变量类型.这一点是不会改变的,但是2015年9月创始人 Guido van Rossum 在 Python 3.5 引入了一个类型系统,允许开发 ...
- [py]python中__new__作用
元类metaclass 使劲搞,但是没搞清楚__new__的作用 了解Python元类 Python进阶:一步步理解Python中的元类metaclass Python中的__new__和__init ...
- python中的__new__与__init__,新式类和经典类(2.x)
在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...
- python 中面向对象编程简单总结3--定制类
声明:资源来自慕课网python学习课程,以下只是个人学习总结,仅供参考 1.Python类的特殊方法 特征:以 __ 开头并结尾的方法,比如用于print的__str__() , __getatt ...
- python中操作excel数据 封装成一个类
本文用python中openpyxl库,封装成excel数据的读写方法 from openpyxl import load_workbook from openpyxl.worksheet.works ...
- Python中的私有属性私有方法、类属性类方法以及单例设计模式
私有属性是对象不希望公开的属性,私有方法是对象不希望公开的方法.在定义私有属性和私有方法时,在属性或者方法前,加上__(两个下划线) 公有方法可以通过对象名直接调用,私有方法不能通过对象名直接调用,只 ...
- [py]python中的==和is的区别
is比较id id(a) == id(b) == id(c) a is d #false ==比较值 a==b #true 举个例子:a = 1 b = a c = 1 d = 1.0 这里有3个对象 ...
- Python中xml、字典、json、类四种数据的转换
最近学python,觉得python很强很大很强大,写一个学习随笔,当作留念注:xml.字典.json.类四种数据的转换,从左到右依次转换,即xml要转换为类时,先将xml转换为字典,再将字典转换为j ...
- python 中关于无法导入自己写的类。解决方法
1.错误描述 之前在学习python的过程中,导入自己写入的包文件时.from 自己写的类,会发现没有弹出选择.并且全输入类名称后会发现类名与相关导入的方法会爆红.如图: 2.原因分析 pycharm ...
随机推荐
- 保存对象时碰到的问题-列名 'Discriminator' 无效
今天保存对象时碰到问题: {"列名 'Discriminator' 无效.\r\n列名 'Discriminator' 无效."} 百度了一下,百度找到的一个解决: http:/ ...
- Qt——布局管理器
教程地址 运行截图: 代码: #include "mainwindow.h" #include <QApplication> #include <QHBoxLay ...
- 微信小程序学习指南
作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- 【转载】Eclipse智能提示及快捷键
1.java智能提示 (1). 打开Eclipse,选择打开" Window - Preferences". (2). 在目录树上选择"Java-Editor-Conte ...
- linux mutex
#include <iostream> #include <queue> #include <cstdlib> #include <unistd.h> ...
- c++ 用new创建二维数组~创建指针数组【转】
#include <iostream> using namespace std; void main() { //用new创建一个二维数组,有两种方法,是等价的 //一: ] = ][]; ...
- Makefile 链接静态库
Linux的静态库是以.a结尾的,要连接静态库有两种方法,一种是在编译命令最后直接加上库路径/库名称. 例如你的库在绝对目录/lib/libtest.a下面你就可以这样来编译$(CC) $(CFLAG ...
- C# .ToString()格式化 常用数据转化小总结
1.百分比 ; ; string p = ((double)i / j).ToString("P");//结果:200.00% p = string.Format("{0 ...
- virgo-tomcat-server的生产环境线上配置与管理
Virgo Tomcat Server简称VTS,VTS是一个应用服务器,它是轻量级, 模块化, 基于OSGi系统.与OSGi紧密结合并且可以开发bundles形式的Spring web apps应用 ...
- Android 模糊效果 FastBlur
import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; impor ...