美文网首页
Python>面向对象高级编程

Python>面向对象高级编程

作者: Manegga | 来源:发表于2017-09-10 22:25 被阅读0次

    1. __slots__

    Python里能够随便给实例(instance)增加属性,为了达到限制属性的目的,可以在定义一个class时使用特殊变量__slots__。

    栗子

    >>>class People(object):
    ...    __slots__ = ('head', 'foot', 'hand') # 使用__slots__限制属性
    ...    
    
    >>>p = People() # 创建实例p
    >>>p.head = 'circle' # 添加属性head
    >>>p.head
    'circle'
    
    >>>p.tale = 'none' #尝试添加属性tale,失败
    Traceback (most recent call last):
    
      File "<ipython-input-144-0df7f091df13>", line 1, in <module>
        p.tale = 'none'
    
    AttributeError: 'People' object has no attribute 'tale'
    
    

    不妨碍添加类属性

    >>>People.tale = 'None'
    >>>p.tale
    'None'
    

    不妨碍子类的实例添加属性

    >>>class Student(People):
    ...    pass
    >>>s = Student()
    >>>s.sight = 'Weak'
    >>>s.sight
    'Weak'
    

    2. @property

    @property能让类的方法变得像属性。

    具体如下:

    class Screen(object):
       
       @property
       def width(self):
           return self._width
       
       @width.setter
       def width(self, value):
           if not isinstance(value, (int, float)):
               raise ValueError('Must be int or float!')
           elif value <= 0:
               raise ValueError('Must be positive!')
           else:
               self._width = value
       
       @property
       def height(self):
           return self._height
       
       @height.setter
       def height(self, value):
           if not isinstance(value, (int, float)):
               raise ValueError('must be int or float!')
           elif value <= 0:
               raise ValueError('Must be positive!')
           else:
               self._height = value
               
       @property
       def resolution(self):
           return self._width * self._height
       
       
    #测试
    
    s = Screen()
    s.width = 1024
    s.height = 768
    print(s.resolution)
    assert s.resolution == 786432, '1024 * 768 = %d ?' % s.resolution
    
    
    #测试结果
    
    #786432
    
    

    上面的栗子通过@property将width(), height()和resolution()变成了属性一样进行赋值和引用。而s.resolution只可引用,不可修改。

    3. 多重继承

    多重继承指的是一个子类可以拥有多个父类。比如:有“学校人员”类和“青少年”类,然后创建一个“学生”的子类同时继承前面提到的两个类。

    多重继承这个概念很好理解,但是细想一下,然后查阅一下,发现其实很是复杂。

    复杂的地方在于多重继承中,多个父类若有相同属性,谁的优先级更高。优先级可以通过mro得到。

    想更详细的了解点这里

    例子:

    class A(object):
        pass
    
    class B(object):
        pass
    
    class C(A):
        pass
    
    class D(C, B):
        pass
    
    class E(D):
        pass
    
    class G(D):
        pass
    
    class F(E):
        pass
    
    class H(F, G):
        pass
    
    #测试
    print(H.__mro__)
    
    
    #树状图
    #    A       B
    #    |      /
    #    C     /
    #     \   /
    #       D
    #     /  \
    #   E     G
    #  /     | 
    # F     |  
    #  \   |
    #    H 
    

    结果:

    (<class '__main__.H'>, <class '__main__.F'>, <class '__main__.E'>, <class '__main__.G'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
    

    也就是:H>F>E>G>D>C>A>B

    super().init

    super()更专业的解说在这里

    把上面的代码改一下(定义了属性):

    class A(object):
        def __init__(self):
            print('Enter A')
            super().__init__()
            print('Leave A')
    
    class B(object):
        def __init__(self):
            print('Enter B')
            super().__init__()
            print('Leave B')
    
    class C(A):
        def __init__(self):
            print('Enter C')
            super().__init__()
            print('Leave C')
    
    class D(C, B):
        def __init__(self):
            print('Enter D')
            super().__init__()
            print('Leave D')
    
    class E(D):
        def __init__(self):
            print('Enter E')
            super().__init__()
            print('Leave E')
    
    class G(D):
        def __init__(self):
            print('Enter G')
            super().__init__()
            print('Leave G')
    
    class F(E):
        def __init__(self):
            print('Enter F')
            super().__init__()
            print('Leave F')
    
    class H(F, G):
        def __init__(self):
            print('Enter H')
            super().__init__()
            print('Leave H')
    
    #测试
    h = H()
    print(h)
    
    
    #树状图
    #    A       B
    #    |      /
    #    C     /
    #     \   /
    #       D
    #     /  \
    #   E     G
    #  /     | 
    # F     |  
    #  \   |
    #    H 
    

    结果:

    Enter H
    Enter F
    Enter E
    Enter G
    Enter D
    Enter C
    Enter A
    Enter B
    Leave B
    Leave A
    Leave C
    Leave D
    Leave G
    Leave E
    Leave F
    Leave H
    

    小结

    1. super().init()一旦用了,最好一直用,别换别的东西。
    2. 多重继承虽好,但是还是不要搞太复杂了。

    相关文章

      网友评论

          本文标题:Python>面向对象高级编程

          本文链接:https://www.haomeiwen.com/subject/dngtsxtx.html