新式类与经典类的比较

新式类与经典类的区别:

首先:

Python 2.x中默认都是经典类,只有显式继承了object才是新式类

Python 3.x中默认都是新式类,不必显式的继承object

即:新式类都从object继承,经典类不需要

其次:

------新式类对象可以直接通过__class__属性获取自身类型:type

------继承搜索的顺序发生了改变

经典类多继承属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧 —— 即 经典类深度优先

新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动               —— 即 新式类广度优先

------新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中

------新式类增加了__getattribute__方法

------新式类相同父类只执行一次构造函数,经典类重复执行多次。

1、新式类对象可以直接通过__class__属性获取自身类型(type)

 1 #-*- coding:utf-8 -*-
 2 #
 3 class E1(object):
 4     pass
 5
 6 print(‘new_style class‘)
 7 e1 = E1()
 8 print(e1)
 9 print(e1.__class__)
10 print(type(e1))
11
12 ‘‘‘
13 new_style class
14 <__main__.E1 object at 0x7f76acfc2320>
15 <class ‘__main__.E1‘>
16 <class ‘__main__.E1‘>
17
18 ‘‘‘

new_style class

 1 # -*- coding:utf-8 -*-
 2 #
 3
 4 class E:
 5     pass
 6
 7 e = E()
 8 print(‘classic class‘)
 9 print(e)
10 print(type(e))
11 print(e.__class__)
12
13 ‘‘‘
14 classic class
15 <__main__.E instance at 0x7f31b429afc8>
16 <type ‘instance‘>
17 __main__.E
18
19 ‘‘‘

classic class

在Python2.7下运行,E1是定义的新式类。那么输出e1的时候,不论是type(e1),还是e1.__class__都是输出的<class ‘__main__.E1‘>。

2、经典类深度优先,新式类广度优先

 1 #-*- coding:utf-8 -*-
 2 #
 3
 4 class A(object):
 5     ‘‘‘
 6     新式类,作为所有类的基类
 7     ‘‘‘
 8     def foo(self):
 9         print(‘class A‘)
10
11 class A1:
12     ‘‘‘
13     经典类,作为所有类的基类
14     ‘‘‘
15     def foo(self):
16         print(‘class A1‘)
17
18 class C(A):
19     pass
20
21 class C1(A1):
22     pass
23
24 class D(A):
25     def foo(self):
26         print(‘class D‘)
27
28 class D1(A1):
29     def foo(self):
30         print(‘class D1‘)
31
32 class E(C, D):
33     pass
34
35 class E1(C1, D1):
36     pass
37
38
39 e = E()
40 e.foo()
41 e1 = E1()
42 e1.foo()
43
44 ‘‘‘
45 class D
46 class A1
47 ‘‘‘

新式类与经典类的基础顺序

因为A新式类,对于继承A类都是新式类,首先要查找类E中是否有foo(),如果没有则按顺序查找C->D->A。它是一种广度优先查找方式。

因为A1经典类,对于继承A1类都是经典类,首先要查找类E1中是否有foo(),如果没有则按顺序查找C1->A1->D1。它是一种深度优先查找方式。

3、新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4
 5 class A(object):
 6     __slots__ = (‘name‘, ‘age‘)
 7
 8 class A1:
 9     __slots__ = (‘name‘, ‘age‘)
10
11
12 a = A()
13 a1 = A1()
14
15 a.name1 = ‘a‘
16 a1.name1 = ‘a1‘
17
18 ‘‘‘
19 Traceback (most recent call last):
20   File "E:/python14_workspace/s14/day06/py_1.py", line 15, in <module>
21     a.name1 = ‘a‘
22 AttributeError: ‘A‘ object has no attribute ‘name1‘
23 ‘‘‘

新式类增加属性锁定功能

A是新式类添加了__slots__ 属性,所以只允许添加 ‘name’ 和 ‘age’ 两种属性

A1经典类__slots__ 属性不起作用。

通常每一个实例都会有一个__dict__属性,用来记录实例中所有的属性和方法,也是通过这个字典,可以让实例绑定任意的属性;

而__slots__属性作用就是,当一个类C有比较少的变量,而且拥有__slots__属性时,类C的实例就没有__dict__属性,而是把变量的值存在一个固定的地方。如果试图访问一个__slots__中没有的属性,实例就会报错。这样操作有什么好处呢?__slots__属性虽然令实例失去了绑定任意属性的便利,但是因为每一个实例没有__dict__属性,却能有效节省每一个实例的内存消耗,有利于生成小而精干的实例。

 1 #-*- coding:utf-8 -*-
 2 #
 3
 4 class A(object):
 5     __slots__ = (‘name‘, ‘age‘)
 6
 7 class A1:
 8     __slots__ = (‘name‘, ‘age‘)
 9
10
11 a = A()
12 a1 = A1()
13
14 # a.name1 = ‘a‘
15 a1.name1 = ‘a1‘
16 a1.name = ‘Tom‘
17 a1.age = ‘23‘
18 a.name = ‘Tim‘
19 a.age = ‘22‘
20 print(a1.__dict__)
21 print(a.__slots__)
22 print(a.name, a.age)
23 print(a.__dict__)
24
25 ‘‘‘
26 {‘age‘: ‘23‘, ‘name‘: ‘Tom‘, ‘name1‘: ‘a1‘}
27 (‘name‘, ‘age‘)
28 (‘Tim‘, ‘22‘)
29 Traceback (most recent call last):
30   File "py_4.py", line 21, in <module>
31       print(a.__dict__)
32 AttributeError: ‘A‘ object has no attribute ‘__dict__‘
33 ‘‘‘

新式类的__slots__特性

4、新式类增加了__getattribute__方法

 1 #-*- coding:utf-8 -*-
 2 #
 3
 4 class A(object):
 5     def __getattribute__(self, *args, **kwargs):
 6         print(‘A.__getattribute__‘)
 7
 8 class A1:
 9     def __getattribute__(self, *args, **kwargs):
10         print(‘A1.__getattribute__‘)
11
12
13 a = A()
14 a1 = A1()
15
16 a.test
17 print(‘============‘)
18 a1.test
19
20 ‘‘‘
21 A.__getattribute__
22 ============
23 Traceback (most recent call last):
24   File "py_5.py", line 18, in <module>
25       a1.test
26 AttributeError: A1 instance has no attribute ‘test‘
27 ‘‘‘

新式类__getattribute__()方法

可以看出A是新式类,每次通过实例访问属性,都会经过__getattribute__函数,A1不会调用__getattribute__所以出错了。

5、新式类相同父类只执行一次构造函数,经典类重复执行多次。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4
 5 class A:
 6     def __init__(self):
 7         print(‘a‘, end=‘‘)
 8
 9 class B(A):
10     def __init__(self):
11         A().__init__()
12         print(‘b‘, end=‘‘)
13
14 class C(A):
15     def __init__(self):
16         A().__init__()
17         print(‘c‘, end=‘‘)
18
19 class D(B, C):
20     def __init__(self):
21         B().__init__()
22         C().__init__()
23         print(‘d‘, end=‘‘)
24
25 class E(D, A):
26     def __init__(self):
27         D().__init__()
28         A().__init__()
29         print(‘e‘, end=‘‘)
30
31 d = D()
32 print(‘‘)
33 e = E()
34
35 ‘‘‘
36 aabaabaacaacd
37 aabaabaacaacdaabaabaacaacdaae
38 ‘‘‘

经典类构造函数重复执行

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # Author: antcolonies
 4
 5 class A(object):
 6     def __init__(self):
 7         print(‘a‘, end=‘‘)
 8
 9 class B(A):
10     def __init__(self):
11         super(B,self).__init__()
12         print(‘b‘, end=‘‘)
13
14 class C(A):
15     def __init__(self):
16         super(C, self).__init__()
17         print(‘c‘, end=‘‘)
18
19 class D(B, C):
20     def __init__(self):
21         super(D, self).__init__()
22         print(‘d‘, end=‘‘)
23
24 class E(D, A):
25     def __init__(self):
26         super(E, self).__init__()
27         print(‘e‘, end=‘‘)
28
29 d = D()
30 print(‘‘)
31 e = E()
32
33 ‘‘‘
34 acbd
35 acbde
36 ‘‘‘

新式类构造函数指执行一次即可

时间: 2024-10-18 12:45:39

新式类与经典类的比较的相关文章

新式类 VS 经典类

一.概述 Python中支持多继承,也就是一个子类可以继承多个父类/基类.当一个调用一个自身没有定义的属性时,它是按照何种顺序去父类中寻找的呢?尤其是当众多父类中都包含有同名的属性,这就涉及到新式类 和 经典类的区别. 二.多继承 1 class Food(object): 2 3 def __init__(self, name, color): 4 self.name = name 5 self.color = color 6 7 def eatable(self): 8 print("%s

Python新式类和经典类的区别

@Python新式类和经典类的区别 class ClassicClass(): pass class NewStyleClass(object): pass x1 = ClassicClass() x2 = NewStyleClass() print x1.__class__, type(x1) print x2.__class__, type(x2) 输出结果: __main__.ClassicClass <type 'instance'> <class '__main__.NewSt

Python新式类与经典类的区别

1.新式类与经典类 在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性:反之,即不由任意内置类型派生出的类,则称之为“经典类”. “新式类”和“经典类”的区分在Python 3之后就已经不存在,在Python 3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”. 官方文档 https://www.python.org/doc/new

python 新式类和经典类(了解)

在python2中,有新式类和经典类和经典类的区别: 新式类 继承自object或object的子类,这样的类就叫新式类. class A(object): pass print(A.__bases__) 结果: (<class 'object'>,) 经典类 没有继承object或object的子类. >>> class A: ... pass ... >>> A.__bases__ () >>> 而在python3中不再有这种区别,所有

03-python的新式类和经典类区别

新式类就是  class person(object): 这种形式的, 从py2.2 开始出现的 新式类添加了: __name__ is the attribute's name. __doc__ is the attribute's docstring. __get__(object) is a method that retrieves the attribute value from object. __set__(object, value) sets the attribute on

python中新式类和经典类的区别

1).python在类中的定义在py2-3版本上是使用的有新式类和经典类两种情况,在新式类和经典类的定义中最主要的区别是在定义类的时候是否出现引用object;如:经典类:Class 类名::而新式类定义的时候使用Class 类名(object): 2).定义来源:在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性:反之,即不由任意内置类型派生出的类,则称之为“经典类”. 3).衍生:“新式类”和“经典

python中的__new__与__init__,新式类和经典类(2.x)

在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1. 新式类对象可以直接通过__class__属性获取自身类型:type 2. 继承搜索的顺序发生了改变,经典类多继承时属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧(即深度优先搜索);新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动 例子: 经典类: 搜索顺序是(D,B,A,C)>>&

Python 新式类与经典类

新式类,经典类 查询匹配 广度查询 横着对每个类进行查询 深度查询 无视平级类,直接寻找下级类 #python 3.0 #新式类 广度查询 #经典类 广度查询 #python 2.0 #新式类 广度查询 #经典类 深度查询

python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。

单例模式的写法非常多,但常规型的单例模式就是这样写的,各种代码可能略有差异,但核心就是要搞清楚类属性 实例属性,就很容易写出来,原理完全一模一样. 如下: 源码: class A(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, '__inst'): print('执行new') obj = super(A, cls).__new__(cls) setattr(cls, '__inst', obj) return ob