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
小结
- super().init()一旦用了,最好一直用,别换别的东西。
- 多重继承虽好,但是还是不要搞太复杂了。