zoukankan      html  css  js  c++  java
  • 新式类与经典类的比较

    新式类与经典类的区别:

    首先:

    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 '''
    新式类构造函数指执行一次即可
  • 相关阅读:
    Java.io.outputstream.PrintStream:打印流
    Codeforces 732F. Tourist Reform (Tarjan缩点)
    退役了
    POJ 3281 Dining (最大流)
    Light oj 1233
    Light oj 1125
    HDU 5521 Meeting (最短路)
    Light oj 1095
    Light oj 1044
    HDU 3549 Flow Problem (dinic模版 && isap模版)
  • 原文地址:https://www.cnblogs.com/ant-colonies/p/6719724.html
Copyright © 2011-2022 走看看