python 零散记录(七)(下) 新式类 旧式类 多继承 mro 类属性 对象属性
python新式类 旧式类:
python2.2之前的类称为旧式类,之后的为新式类。在各自版本中默认声明的类就是各自的新式类或旧式类,但在2.2中声明新式类要手动标明:
这是旧式类为了声明为新式类的方式
class A:
#手写把元类 metaclass 给 type
__metaclass__ = type
pass #或者这样写,效果是一样的
class B(object):
#手动指定继承自object类,object类是最初的类,一切类都是object的子类,是祖宗
pass
对于class A的写法,我的理解是:所谓一切皆对象,类也是对象!类的实例是对象,元类的实例是类...只能这么理解了。类的上头就是元类__metaclass__,然后给元类手动给type。
python多继承,mro:
我并不喜欢这种乱伦式的继承...而且有难写,更难调试。说说自己的理解吧:
1. 当父类们来自不同祖先,并且有同名方法时,顺序在前的父亲会覆盖后面父亲的方法,这个对于新式类旧式类都适用。
2. 当父亲们继承自同一个祖先,新式类的处理是按照宽度优先搜索,旧式类按照深度优先搜索
对于第 1 种,父亲们来自不同祖先,这个新式旧式都适用:
class A:
def f(self):
print 'A' class B:
def f(self):
print 'B' class AB(A,B):
pass ab = AB()
ab.f() #这里调用ab.f()打印的结果跟AB类的父类继承顺序有关,顺序在前的父类方法会覆盖后面的父类方法 #这里打印出的是 :A
对于第2种,继承自相同的祖先时:
class A(object): #声明新式类
def f(self):
print 'A'
class B:
__metaclass__ = type #另一种新式类声明
def f(self):
print 'B'
class BB(B): #BB继承自B,B已经是新式类了,那么BB不用再声明就自然是新式类
#BB重写了B的f方法
def f(self):
print 'BB'
class BBB(B):
#BBB没有重写B的f方法,所以用的还是B的f方法
pass
class BBBB(B):
#BBBB也重写B的f方法:
def f(self):
print 'BBBB'
class Test1(BB,BBB):
pass
t1 = Test1()
t1.f()
#这里会打印BB
class Test2(BB,BBBB): #BB,BBBB都是直接继承自B的,也都重写了B的f方法
pass
t2 = Test2()
t2.f()
#这里会打印BB,因为BB在前,说说咋回事: #首先这里面的都是新式类,Test继承的父亲BB,BBB都来自同一个祖先B,那么开始了:
"""
1 新式类按照宽度优先搜索,所以继承的先后顺序无关结果 2 新式类有一个mro(method resolution order 方法判定次序)的东西,可以类名.__mro__或类名.mro()查看。旧式类是没有的,写的话会报错。 3 具体继承哪个方法:看哪个方法是最新(英文的lasted)重写父类的,就用哪个。如果是统一级别的,也就是同一层级重写的,那就按照先后次序选择
比如Test1:
BB继承B后马上就重写了f方法,而BBB继承B后没有重写f方法而是完全继承自B。这时BB和BBB是同一级别的,都是B的儿子们。
相比较的话,自然可以看出是BB最新重写了f,那f方法就继承BB的。
在比如第二个例子Test2:
BB和BBBB都继承自B,也都重写了B的f方法,有都处于同一级别,这时就看谁在前了,会继承前面的类。
这一条也说明了,继承自不同祖先的情况下,父亲之间都是同辈,没有长幼之分,都是统一级别,所以按照次序选择前面的。
"""
getattr setattr hasattr:
hasattr(a, '属性名/方法名') 返回True or False
setattr(a, '属性名/方法名', 属性/方法的返回值)
getattr(a, '属性名/方法名', 缺省值)
类属性 对象属性:
class C:
#这里的是类属性
a = 0
def __init__(self):
#这里的是对象的属性,对象自己用自己的
pass
当对象中没有指定a的时候,在实例中访问a实际上是访问类属性a
而一旦该实例访问了该属性,那么就会自己保留一份a的拷贝作为自己的对象属性,从此这个对象属性就与类属性无关了,虽然都叫a。也就是说在此之后类和实例两方对各自的a操作互不影响。
但是如果这个属性是可变的,比如list或dict,那么上面一条互不影响就不成立了。是会影响的
class A:
i = 0 #不可变的整数
l = [] #可变的列表
a1 = A()
a2 = A() #先看看有什么
print A.i, a1.i, a2.i #都是 0 #类直接搞i
A.i = 10
print A.i, a1.i, a2.i #三个都变成了10,因为这时都用的是类属性 #这时用对象 a1 搞一下类属性 i
a1.i = 1
print A.i, a1.i, a2.i #只用a1的i属性变了,其他的没变还是10 #再用类直接搞
A.i += 1
print A.i, a1.i, a2.i #只有A和a2的i属性变了,说明a1经过上面独立搞i属性之后,已经把i拷贝到自己那,以后操作都与其他人无关了。 #现在看看搞一搞可变对象 列表
a1.l.append('a1')
print A.l, a1.l, a2.l #都变了 a2.l.append('a2')
print A.l, a1.l, a2.l #又都变了,所以可变对象就不是拷贝完了自己搞,是大伙一起搞的
python 零散记录(七)(下) 新式类 旧式类 多继承 mro 类属性 对象属性的更多相关文章
- python 零散记录(七)(上) 面向对象 类 类的私有化
python面向对象的三大特性: 多态,封装,继承 多态: 在不知道对象到底是什么类型.又想对其做一些操作时,就会用到多态 如 'abc'.count('a') #对字符串使用count函数返回a的数 ...
- java类为什么是单继承。类的继承,实现接口。
java中提供类与类之间提供单继承. 提供多继承会可能出现错误,如:一个类继承了两个父类,而两个父类里面都有show()方法. class Fulei1{ public void show(){ Sy ...
- php函数、类和对象以及类的封装、继承、类的静态方法、静态属性
1.函数 php内置函数可以直接使用,如果没有安装php扩展即可 自定义函数 //函数function 函数名 function dump($var = null){ //支出默认参数 ...
- python 零散记录(一) input与raw_input 数学相关函数 转换字符串的方法
input()与raw_input(): 两者都是接受命令行输入,但区别在于,raw_input()接受原始数据(raw data). #使用input()来提示输入名字 input("en ...
- python 零散记录(五) import的几种方式 序列解包 条件和循环 强调getattr内建函数
用import关键字导入模块的几种方式: #python是自解释的,不必多说,代码本身就是人可读的 import xxx from xxx import xxx from xxx import xx1 ...
- python 零散记录(二) 序列的相关操作 相加 相乘 改变 复制
序列相加: [1,2] + [3,4] == [1,2,3,4] #字符串也是序列的一种 'hello' + 'world' == 'hello world' #但是序列相加只限于相同类型的序列间相加 ...
- python 零散记录(六) callable 函数参数 作用域 递归
callable()函数: 检查对象是否可调用,所谓可调用是指那些具有doc string的东西是可以调用的. 函数的参数变化,可变与不可变对象: 首先,数字 字符串 元组是不可变的,只能替换. 对以 ...
- python 零散记录(四) 强调字典中的键值唯一性 字典的一些常用方法
dict中键只有在值和类型完全相同的时候才视为一个键: mydict = {1:1,':1} #此时mydict[1] 与 mydict['1']是两个不同的键值 dict的一些常用方法: clear ...
- python 零散记录(三) 格式化字符串 字符串相关方法
使用 % 符号格式化字符串: """常用转换说明符:""" #%s: 按照str()方式转换 #%r: 按照repr()方式转换 #%d: ...
随机推荐
- node.js 小爬虫 imooc 2016.03.06
爬虫目标:获取http://www.imooc.com/learn/348网页中的章节标题和视频信息. var http = require('http'); var cheerio = requir ...
- Essential C++ 学习笔记01--基本语法
<Essential C++>1.1-1.4节笔记 1. main 函数 main 函数是代码的入口,若无 main 函数,编译不通过. main 函数通常声明为 int, return ...
- 2015-01-27-从实验出发理解buffer与cache区别-吴伟顺
通过du(find) 与 cat 体现buffer与cache差异实验: 实验表明: 1 通常 buffer << cache 2 "文件系统"相关内容(ino ...
- Sublime Text3 个人使用心得
sublime与webstorm的比较: webstorm真心很强大,强大到能够几乎满足所有前端开发者编程的需求,方便的快捷键操作.代码提示.浏览器查看.工程管理.历史记录(可以找到之前编辑的内容,即 ...
- jquery ajax post, get, javascript ajax post, get 处理
ajax 创建 XMLHttp 对象IE7 以上的版本都支持 XMLHttpRequestIE7 以下的用 ActiveXObject async:true, // 当false 时,当执行完这个才 ...
- 如何判断list中是否包含某个元素
在python中可以通过in和not in关键字来判读一个list中是否包含一个元素: str = ['s','i','m','o','n'] if 'e' in str: print("e ...
- MySQL修改时区的方法小结
这篇文章主要介绍了MySQL修改时区的方法,总结分析了三种常见的MySQL时区修改技巧,包括命令行模式.配置文件方式及代码方式,需要的朋友可以参考下 方法一:通过mysql命令行模式下动态修改 1.1 ...
- 理解依赖注入(IOC)和学习Unity
资料1: IOC:英文全称:Inversion of Control,中文名称:控制反转,它还有个名字叫依赖注入(Dependency Injection). 作用:将各层的对象以松耦合的方式组织在一 ...
- web2py相关-------------------------------(一)初遇
在第一次换工作的时候,希望转行 做编程,就面试了很多家,很多人问我 懂不懂html 书写,我非常诚实的告诉他们不会. 当然那时我很天真的认为,只要自己愿意学习这些都不是问题,事实证明人的学习能力是很快 ...
- web2.0最全的国外API应用集合
web2.0最全的国外API应用集合 原文地址:http://www.buguat.com/post/98.html 2.0时代,越来越多的API被大家广泛应用,如果你还不了解API是何物,请看这里的 ...