1. __slots__
Python里能夠隨便給實(shí)例(instance)增加屬性,為了達(dá)到限制屬性的目的,可以在定義一個(gè)class時(shí)使用特殊變量__slots__。
栗子
>>>class People(object):
... __slots__ = ('head', 'foot', 'hand') # 使用__slots__限制屬性
...
>>>p = People() # 創(chuàng)建實(shí)例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'
不妨礙子類的實(shí)例添加屬性
>>>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
#測試結(jié)果
#786432
上面的栗子通過@property將width(), height()和resolution()變成了屬性一樣進(jìn)行賦值和引用。而s.resolution只可引用,不可修改。
3. 多重繼承
多重繼承指的是一個(gè)子類可以擁有多個(gè)父類。比如:有“學(xué)校人員”類和“青少年”類,然后創(chuàng)建一個(gè)“學(xué)生”的子類同時(shí)繼承前面提到的兩個(gè)類。
多重繼承這個(gè)概念很好理解,但是細(xì)想一下,然后查閱一下,發(fā)現(xiàn)其實(shí)很是復(fù)雜。
復(fù)雜的地方在于多重繼承中,多個(gè)父類若有相同屬性,誰的優(yōu)先級(jí)更高。優(yōu)先級(jí)可以通過mro得到。
想更詳細(xì)的了解點(diǎn)這里
例子:
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
結(jié)果:
(<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()更專業(yè)的解說在這里。
把上面的代碼改一下(定義了屬性):
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
結(jié)果:
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
小結(jié)
- super().init()一旦用了,最好一直用,別換別的東西。
- 多重繼承雖好,但是還是不要搞太復(fù)雜了。