从Python2.2开始,Python引入了 new style class(新式类)
新式类跟经典类的差别主要是以下几点:
新式类对象可以直接通过__class__属性获取自身类型:type
[python]view plaincopy
- classE:
- pass
- classE1(object):
- pass
- e=E()
- print"经典类"
- printe
- printtype(e)
- printe.__class__
- print"新式类"
- e1=E1()
- printe1
- printe1.__class__
- printtype(e1)
[python]view plaincopy
- 经典类
- <__main__.Einstanceat0x0000000002250B08>
- <type'instance'>
- __main__.E
- 新式类
- <__main__.E1objectat0x0000000002248710>
- <class'__main__.E1'>
- <class'__main__.E1'>
我使用的是python2.7。
E1是定义的新式类。那么输输出e1的时候,不论是type(e1),还是e1.__class__都是输出的<class '__main__.E1'>。
2. 继承搜索的顺序发生了改变,经典类多继承属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧;新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动
[python]view plaincopy
- classA(object):
- deffoo(self):
- print"classA"
- classA1():
- deffoo(self):
- print"classA1"
- classC(A):
- pass
- classC1(A1):
- pass
- classD(A):
- deffoo(self):
- print"classD"
- classD1(A1):
- deffoo(self):
- print"classD1"
- classE(C,D):
- pass
- classE1(C1,D1):
- pass
- e=E()
- e.foo()
- e1=E1()
- e1.foo()
输出
[python]view plaincopy
- classD
- classA1
因为A新式类,对于继承A类都是新式类,首先要查找类E中是否有foo(),如果没有则按顺序查找C->D->A。它是一种广度优先查找方式。
因为A1经典类,对于继承A1类都是经典类,首先要查找类E1中是否有foo(),如果没有则按顺序查找C1->A1->D1。它是一种深度优先查找方式。
3. 新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中。
比如只允许对A实例添加name和age属性:
[python]view plaincopy
- classA(object):
- __slots__=('name','age')
- classA1():
- __slots__=('name','age')
- a1=A1()
- a=A()
- a1.name1="a1"
- a.name1="a"
A是新式类添加了__slots__ 属性,所以只允许添加name age
A1经典类__slots__ 属性没用,
[python]view plaincopy
- Traceback(mostrecentcalllast):
- File"t.py",line13,in<module>
- a.name1="a"
- AttributeError:'A'objecthasnoattribute'name1'
所以a.name是会出错的
通常每一个实例都会有一个__dict__属性,用来记录实例中所有的属性和方法,也是通过这个字典,可以让实例绑定任意的属性
而__slots__属性作用就是,当类C有比较少的变量,而且拥有__slots__属性时,
类C的实例 就没有__dict__属性,而是把变量的值存在一个固定的地方。如果试图访问一个__slots__中没有
的属性,实例就会报错。这样操作有什么好处呢?__slots__属性虽然令实例失去了绑定任意属性的便利,
但是因为每一个实例没有__dict__属性,却能有效节省每一个实例的内存消耗,有利于生成小而精
干的实例。
4. 新式类增加了__getattribute__方法
[python]view plaincopy
- classA(object):
- def__getattribute__(self,*args,**kwargs):
- print"A.__getattribute__"
- classA1():
- def__getattribute__(self,*args,**kwargs):
- print"A1.__getattribute__"
- a1=A1()
- a=A()
- a.test
- print"========="
- a1.test
[python]view plaincopy
- A.__getattribute__
- =========
- Traceback(mostrecentcalllast):
- File"t.py",line18,in<module>
- a1.test
- AttributeError:A1instancehasnoattribute'test'
可以看出A是新式类,每次通过实例访问属性,都会经过__getattribute__函数,
A1不会调用__getattribute__所以出错了
Python 2.x中默认都是经典类,只有显式继承了object才是新式类
Python 3.x中默认都是新式类,不必显式的继承object
- Python数据挖掘实例(实时更新)
- AttributeError:“MatrixFactorizationModel”对象没有属性“sav
- Python------类的结构细分,异常处理,方法,属性
- Python进阶----类的结构(公有成员 , 私有成员(私有属性,私有方法
- AttributeError:'Flask'对象没有属性'login_manager' - Login_Ma
- 关于Python的属性、参数、方法的解释、区别
- 使用Python编写简单的端口扫描器的实例分享【转】
- python函数的属性
- UNIX-LINUX编程实践教程->第八章->实例代码注解->写一个简单的sh
随机推荐
-
android 重力感应初步认识
-
Android调用输入法软键盘,返回输入的内容
-
android中使用afinal一行代码显示网络图
-
Android文件系统保护——dmverity
-
Camera Flash的获得权限
-
2.5.3 使用alertDialog创建自定义对话框
-
Android 已发行多年,移动 App 已经趋近饱
-
Fetching https://dl-ssl.google.com/and
-
登录案例_android
-
Android统计图集合源码