码迷,mamicode.com
首页 > 编程语言 > 详细

python基础整理笔记(七)

时间:2016-06-26 11:28:09      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

一. python的类属性与实例属性的注意点

 1 class TestAtt():
 2     aaa = 10
 3 
 4 def main():
 5     # case 1
 6     obj1 = TestAtt()
 7     obj2 = TestAtt()
 8     print obj1.aaa, obj2.aaa, TestAtt.aaa
 9 
10     # case 2
11     obj1.aaa += 1
12     print obj1.aaa, obj2.aaa, TestAtt.aaa
13 
14     # case 3
15     TestAtt.aaa += 2
16     print obj1.aaa, obj2.aaa, TestAtt.aaa
17 
18 if __name__ == __main__:
19     main()

一段示例代码,一个类TestAtt只有一个类对象,然后通过改变其不同对象的属性和类的属性,结果如下:

技术分享

改变的似乎挺特殊,分析原因如下:

python中的属性获取机制,是从底层的对象到上层中一点点找的;在第一次获取obj1.aaa, obj2.aaa的时候,因为这个类并没有初始化实例的属性,所以其实obj1和obj2并没有aaa这个属性,所以实质上obj1.aaa, obj2.aaa都是TestAtt.aaa。

而对于 case2,obj1.aaa += 1这个操作实际上是给obj1这个实例创建了aaa的属性(以TestAtt.aaa的值再加1),所以从case2来看它的值就单独改变了,而且在case3中也没再受到影响。

现在我把代码修改如下再运行下结果,打印出每个实例的__dict__:

 1 def main():
 2     # case 1
 3     obj1 = TestAtt()
 4     obj2 = TestAtt()
 5     print obj1.aaa, obj2.aaa, TestAtt.aaa
 6     print obj1.__dict__
 7     print obj2.__dict__
 8 
 9     # case 2
10     obj1.aaa += 1
11     print obj1.aaa, obj2.aaa, TestAtt.aaa
12     print obj1.__dict__
13     print obj2.__dict__
14 
15     # case 3
16     TestAtt.aaa += 2
17     print obj1.aaa, obj2.aaa, TestAtt.aaa
18     print obj1.__dict__
19     print obj2.__dict__

技术分享

这样看就很明显,可以证明上述的情况。

 

二. python多重继承注意点:

在python2.7里面有经典类和新式类之分,前者定义时没有明式的继承,后者会继承object类。

在多重继承后寻找属性的时候,二者的行为有一个明显的区别:

经典类是深度优先地搜索——会在条继承链上线搜索到底,再到下一个优先级的继承链上搜索,以此类推。

形式类是广度优先地搜索——在同一代际的继承者们之间按照优先级水平搜索,这一代际搜索不到,再向更上层的父辈里寻找,一次类推。

示例代码如下:

 1 class A(object):  
 2     def foo(self):  
 3         print "class A" 
 4         
 5 class A1():  
 6     def foo(self):  
 7         print "class A1"  
 8         
 9 class C(A):  
10     pass
11     
12 class C1(A1):  
13     pass
14     
15 class D(A):  
16     def foo(self):  
17         print "class D"  
18     
19 class D1(A1):  
20     def foo(self):  
21         print "class D1"  
22   
23 class E(C, D):  
24     pass
25     
26 class E1(C1, D1):  
27     pass
28 
29 e = E()
30 e.foo()
31   
32 e1 = E1()
33 e1.foo()

这里字母后带数字的是经典类,不带的是新式类,然后我们运行一下结果:

技术分享

证明了上面的说法。

 但是我们看看在python3中的表现,一样的代码结果如下:

技术分享

所以在python3中,其实并没有所谓经典类和形式类的区别了,而且多重继承的顺序统一为深度优先了。

python基础整理笔记(七)

标签:

原文地址:http://www.cnblogs.com/nigel-woo/p/5617504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!