python基础整理笔记(七)
一. python的类属性与实例属性的注意点
class TestAtt():
aaa = 10 def main():
# case 1
obj1 = TestAtt()
obj2 = TestAtt()
print obj1.aaa, obj2.aaa, TestAtt.aaa # case 2
obj1.aaa += 1
print obj1.aaa, obj2.aaa, TestAtt.aaa # case 3
TestAtt.aaa += 2
print obj1.aaa, obj2.aaa, TestAtt.aaa if __name__ == '__main__':
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__:
def main():
# case 1
obj1 = TestAtt()
obj2 = TestAtt()
print obj1.aaa, obj2.aaa, TestAtt.aaa
print obj1.__dict__
print obj2.__dict__ # case 2
obj1.aaa += 1
print obj1.aaa, obj2.aaa, TestAtt.aaa
print obj1.__dict__
print obj2.__dict__ # case 3
TestAtt.aaa += 2
print obj1.aaa, obj2.aaa, TestAtt.aaa
print obj1.__dict__
print obj2.__dict__

这样看就很明显,可以证明上述的情况。
二. python多重继承注意点:
在python2.7里面有经典类和新式类之分,前者定义时没有明式的继承,后者会继承object类。
在多重继承后寻找属性的时候,二者的行为有一个明显的区别:
经典类是深度优先地搜索——会在条继承链上线搜索到底,再到下一个优先级的继承链上搜索,以此类推。外部的优先级是从左到右。
形式类是广度优先地搜索——在同一代际的继承者们之间按照优先级水平搜索,这一代际搜索不到,再向更上层的父辈里寻找,以此类推。外部的优先级是从左到右。
示例代码如下:
class A(object):
def foo(self):
print "class A" class A1():
def foo(self):
print "class A1" class C(A):
pass class C1(A1):
pass class D(A):
def foo(self):
print "class D" class D1(A1):
def foo(self):
print "class D1" class E(C, D):
pass class E1(C1, D1):
pass e = E()
e.foo() e1 = E1()
e1.foo()
这里字母后带数字的是经典类,不带的是新式类,然后我们运行一下结果:

证明了上面的说法。
但是我们看看在python3中的表现,一样的代码结果如下:

所以在python3中,其实并没有所谓经典类和形式类的区别了,而且多重继承的顺序统一为深度优先了。
三. python特殊的继承多个类的特性
在python中,一个类其实可以继承多个不同的类,这在静态语言里面一般是不允许的,因为可能会存在歧义,而在python中解决歧义的方法,是通过确定继承的顺序来解决的,具体的顺序有几种情况,我在上面的章节已经提过了。
这里要说的一种设计思路叫“maxin”,在python中就可以通过继承多个类的方式来实现之。
看看所谓的maxin的定义:

根据stackoverflow里面的说法,使用maxin的场景如下:
- 你希望给一个类提供很多可选的特征(feature).
- 你希望在很多不同的类中使用一个特定的特征(feature).
看着比较抽象...其实这就是一种更好的减少重复代码的模式。举个例子~(这是赖勇浩博客里的一个例子)
比如我们有个基类是fruit,然后有子类apple和banana;fruit有个方法是is_gift_fruit,表示是否可以作为礼物,而apple和banana表现是不一样的,那么实现如下:
class Fruit(object):
pass class Apple(Fruit):
def is_gift_fruit(self):
return True class Banana(Fruit):
def is_gift_fruit(self):
return False
如果还有增加很多不同水果的子类,那么这个 is_gift_fruit就会显得很不好,重复很多并且不易维护,这时候就可以定义一个新的类,就是为了体现是否可以作为礼物的类。然后用到多继承的方式来实现一样的效果,代码如下:
class Fruit(object):
pass class GiftMixin(object):
def is_gift_fruit(self):
return True class NotGiftMixin(object):
def is_gift_fruit(self):
return False class Apple(GiftMixin, Fruit):pass
class Banana(NotGiftMixin, Fruit):pass
有了上述思路,我们就可以继续再添加更多不同的行为,都将他们抽象为新的maxin类,而不用写很多臃肿的,多重继承的中间子类;比如我们可以增加是进口的还是国产的类,是有机的还是转基因的类,示例如下:
class Fruit(object):
pass class GiftMixin(object):
def is_gift_fruit(self):
return True class NotGiftMixin(object):
def is_gift_fruit(self):
return False class NativeMixin(object):
def Locality(self):
return 'Native' class ForeignMixin(object):
def Locality(self):
return 'Foreign' class OrganicMixin(object):
def Organic(self):
return 'Organic' class TransgenosisMixin(object):
def Transgenosis(self):
return 'Transgenosis' class Apple(GiftMixin, ForeignMixin, OrganicMixin, Fruit):pass
class Banana(NotGiftMixin, NativeMixin, TransgenosisMixin, Fruit):pass
class Pear(NotGiftMixin, NativeMixin, OrganicMixin, Fruit):pass
这样代码就会显得很好看,而且如果还有蔬菜,豆类等等的基类,我们也可以复用上这些maxin的类。
python基础整理笔记(七)的更多相关文章
- python基础整理笔记(九)
一. socket过程中注意的点 1. 黏包问题 所谓的黏包就是指,在TCP传输中,因为发送出来的信息,在接受者都是从系统的缓冲区里拿到的,如果多条消息积压在一起没有被读取,则后面读取时可能无法分辨消 ...
- python基础整理笔记(五)
一. python中正则表达式的一些查漏补缺 1. 给括号里分组的表达式加上别名:以便之后通过groupdict方法来方便地获取. 2. 将之前取名为"name"的分组所获得的 ...
- python基础整理笔记(四)
一. python 打开文件的方法 1. python中使用open函数打开文件,需要设定的参数包括文件的路径和打开的模式.示例如下: f = open('a.txt', 'r+') 2. f为打开文 ...
- python基础整理笔记(二)
一. 列表 1. 创建实例: a = [1,2,3] b = list() 2. 主要支持的操作及其时间复杂度如下: 3. 其他 python中的列表,在内存中实际存储的形式其实是分散的存储,比较类似 ...
- python基础整理笔记(一)
一. 编码 1. 在python2里,加载py文件会对字符进行编码,需要在文件头上的注释里注明编码类型(不加则默认是ascII). # -*- coding: utf-8 -*- print 'hel ...
- python基础整理笔记(八)
一. python反射的方式来调用方法属性 反射主要指的就是hasattr.getattr.setattr.delattr这四个函数,作用分别是检查是否含有某成员.获取成员.设置成员.删除成员. 此外 ...
- python基础整理笔记(三)
一. python的几种入参形式:1.普通参数: 普通参数就是最一般的参数传递形式.函数定义处会定义需要的形参,然后函数调用处,需要与形参一一对应地传入实参. 示例: def f(a, b): pri ...
- python基础整理笔记(六)
一. 关于hashlib模块的一些注意点 hashlib模块用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512, MD ...
- 0003.5-20180422-自动化第四章-python基础学习笔记--脚本
0003.5-20180422-自动化第四章-python基础学习笔记--脚本 1-shopping """ v = [ {"name": " ...
随机推荐
- 在使用dot。js中的值中有空格出现后,进行去除
title= {{= x.replace(/ /g,' ') 通过replace将数据进行处理再展示
- QuickHit快速击键小程序 --S2.4.5
我们现在要做一个项目 一个小小的程序 叫做快速击键 很明了的目的 就是在规定时间内,每次出现一组字母的组合,这个字母只能在DFJK中生成 然后输入相应的文字,按回车 自动判断输入的是否正确 在规定时间 ...
- OpenLDAP,一登录系统就修改密码
http://guodayong.blog.51cto.com/263451/d-2 郭大勇的博客 1:修改配置文件 在前面打开注释 moduleload ppolicy.la modulepat ...
- 'Missing recommended icon file - The bundle does not contain an app icon for iPhone / iPod Touch of exactly '120x120' pixels, in .png format'
创建120像素的高分辨率和60个像素定期如上,苹果文档中提到,并设置名称的新图标.例如,icon-120.png和icon-152.png. 将这个图标到你的项目资源文件夹并添加该图标到项目: 在此之 ...
- js中常用的操作
1.js中常用的数组操作 2.js中常用的字符串操作 3.js中常用的时间日期操作 4.定时器
- [译]2016年深度学习的主要进展(译自:The Major Advancements in Deep Learning in 2016)
译自:The Major Advancements in Deep Learning in 2016 建议阅读时间:10分钟 https://tryolabs.com/blog/2016/12/06/ ...
- JavaWeb 学习006-4个页面,5条sql语句(添加、查看、修改、删除)
今天遇到的问题: 1. 在list页面上添加信息时候,跳转到doAdd页面后,点击保存按钮,能够跳转回list页面,但是新增的信息不能显示出来,就像是没有执行添加操作一样. 这是什么问题? ①是不是到 ...
- MVC4 本地正常运行,发布到IIS7->403 - 禁止访问: 访问被拒绝。
代码编写完成,计划发布一个版本测试,没想到发布到IIS7 竟然报错“403-禁止访问”.还真第一次遇到这种问题..... 折腾了半天,终于解决. 1.提示报错403: 禁止访问: 访问被拒绝.您无权使 ...
- CSS浏览器兼容问题总结
为什么会出现浏览器兼容问题? 由于各大主流浏览器是不同的厂家开发的,所以使用的核心也不相同,架构代码很难重合,就会产生各种各样的bug. IE6中常见的css解析bug 1)默认高度(IE6)部分块元 ...
- ASP.NET MVC+Entity Framework 访问数据库
Entity Framework 4.1支持代码优先(code first)编程模式:即可以先创建模型类,然后通过配置在EF4.1下动态生成数据库. 下面演示两种情形: 1.代码优先模式下,asp.n ...