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 '''
    新式类构造函数指执行一次即可
  • 相关阅读:
    android阅读器开发
    Android开源库
    Android开源项目分类汇总
    java 读取显示txt内容(Swing)
    Java 图形用户界面设计 (Swing)
    Java读取txt文件,换行写txt文件
    出国旅行口语必备300句
    100-days:nine
    100-days: eight
    The Attention Merchants
  • 原文地址:https://www.cnblogs.com/ant-colonies/p/6719724.html
Copyright © 2011-2022 走看看