Python>面向对象高级编程

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 "", line 1, in 
    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 

结果:

(, , , , , , , , )

也就是: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>面向对象高级编程)