博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python基础整理笔记(七)
阅读量:5270 次
发布时间:2019-06-14

本文共 4164 字,大约阅读时间需要 13 分钟。

一. 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 211     obj1.aaa += 112     print obj1.aaa, obj2.aaa, TestAtt.aaa13 14     # case 315     TestAtt.aaa += 216     print obj1.aaa, obj2.aaa, TestAtt.aaa17 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 210     obj1.aaa += 111     print obj1.aaa, obj2.aaa, TestAtt.aaa12     print obj1.__dict__13     print obj2.__dict__14 15     # case 316     TestAtt.aaa += 217     print obj1.aaa, obj2.aaa, TestAtt.aaa18     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     pass11     12 class C1(A1):  13     pass14     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     pass25     26 class E1(C1, D1):  27     pass28 29 e = E()30 e.foo()31   32 e1 = E1()33 e1.foo()

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

证明了上面的说法。

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

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

 

 

三.  python特殊的继承多个类的特性

在python中,一个类其实可以继承多个不同的类,这在静态语言里面一般是不允许的,因为可能会存在歧义,而在python中解决歧义的方法,是通过确定继承的顺序来解决的,具体的顺序有几种情况,我在上面的章节已经提过了。

这里要说的一种设计思路叫“maxin”,在python中就可以通过继承多个类的方式来实现之。

看看所谓的maxin的定义:

根据stackoverflow里面的说法,使用maxin的场景如下:

  • 你希望给一个类提供很多可选的特征(feature).
  • 你希望在很多不同的类中使用一个特定的特征(feature).

看着比较抽象...其实这就是一种更好的减少重复代码的模式。举个例子~(这是赖勇浩博客里的一个例子)

比如我们有个基类是fruit,然后有子类apple和banana;fruit有个方法是is_gift_fruit,表示是否可以作为礼物,而apple和banana表现是不一样的,那么实现如下:

1 class Fruit(object): 2        pass 3  4 class Apple(Fruit): 5        def is_gift_fruit(self): 6               return True 7  8 class Banana(Fruit): 9        def is_gift_fruit(self):10               return False

如果还有增加很多不同水果的子类,那么这个 is_gift_fruit就会显得很不好,重复很多并且不易维护,这时候就可以定义一个新的类,就是为了体现是否可以作为礼物的类。然后用到多继承的方式来实现一样的效果,代码如下:

class Fruit(object):       passclass GiftMixin(object):       def is_gift_fruit(self):              return Trueclass NotGiftMixin(object):       def is_gift_fruit(self):              return Falseclass Apple(GiftMixin, Fruit):passclass Banana(NotGiftMixin, Fruit):pass

有了上述思路,我们就可以继续再添加更多不同的行为,都将他们抽象为新的maxin类,而不用写很多臃肿的,多重继承的中间子类;比如我们可以增加是进口的还是国产的类,是有机的还是转基因的类,示例如下:

1 class Fruit(object): 2        pass 3  4 class GiftMixin(object): 5        def is_gift_fruit(self): 6               return True 7  8 class NotGiftMixin(object): 9        def is_gift_fruit(self):10               return False11               12 class NativeMixin(object):13        def Locality(self):14               return 'Native'15               16 class ForeignMixin(object):17        def Locality(self):18               return 'Foreign'19               20 class OrganicMixin(object):21        def Organic(self):22               return 'Organic'23 24 class TransgenosisMixin(object):25        def Transgenosis(self):26               return 'Transgenosis'27               28 class Apple(GiftMixin, ForeignMixin, OrganicMixin, Fruit):pass29 class Banana(NotGiftMixin, NativeMixin, TransgenosisMixin, Fruit):pass30 class  Pear(NotGiftMixin, NativeMixin, OrganicMixin, Fruit):pass

这样代码就会显得很好看,而且如果还有蔬菜,豆类等等的基类,我们也可以复用上这些maxin的类。

 

转载于:https://www.cnblogs.com/nigel-woo/p/5617504.html

你可能感兴趣的文章
Js实现客户端表单的验证
查看>>
python使用input()来接受字符串时一直报错“xxx is not defined”
查看>>
加解密与数据校验
查看>>
stm8s_IAP_xmode串口升级
查看>>
usb 编程知识 总结
查看>>
2016.7.15 落实字符及字符串读取的结果
查看>>
他看了几千份技术简历,愿意把技术简历的秘籍传授给你
查看>>
Struts2学习(三)
查看>>
学习Linux的第十二课时
查看>>
使用电子邮件模板
查看>>
IoC 依赖注入、以及在Spring中的实现
查看>>
机器学习 —— 概率图模型(贝叶斯网络)
查看>>
树、森林和二叉树的转换
查看>>
Array:Missing Number
查看>>
数列有序!
查看>>
jQuery1.11源码分析(2)-----Sizzle源码中的正则表达式[原创]
查看>>
javascript面向对象学习(一)
查看>>
高可用redis 缓存搭建
查看>>
10分钟理解JS引擎的执行机制
查看>>
转 memcached 一致性hash原理
查看>>