本文是筆者學(xué)習(xí)廖雪峰Python3教程的筆記,在此感謝廖老師的教程讓我們這些初學(xué)者能夠一步一步的進(jìn)行下去.如果讀者想學(xué)習(xí)完成的教程,請(qǐng)?jiān)L問(wèn)廖雪峰Python3教程,筆記如有侵權(quán),請(qǐng)告知?jiǎng)h除...
__slots__
- 使用__slots__來(lái)限制實(shí)例能添加的屬性
- 使用__slots__要注意,__slots__定義的屬性僅對(duì)當(dāng)前類實(shí)例起作用床三,對(duì)繼承的子類是不起作用的
- 除非在子類中也定義__slots__起宽,這樣鞋仍,子類實(shí)例允許定義的屬性就是自身的__slots__加上父類的__slots__厂镇。
class Student(object):
__slots__ = ('name', 'age')
@property
- 把一個(gè)getter方法變成屬性诀拭,只需要加上@property就可以了疫向,此時(shí)吹缔,@property本身又創(chuàng)建了另一個(gè)裝飾器@score.setter商佑,負(fù)責(zé)把一個(gè)setter方法變成屬性賦值
class Screen(object):
@property
def width(self):
return self._width
@width.setter
def width(self, value):
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self, value):
self._height = value
@property
def resoluation(self):
return self._width*self._height
MixIn
MixIn是一種多繼承, 只需要在定義類型后面的小括號(hào)里用逗號(hào)分割添加新的繼承類即可
class MyTCPServer(TCPServer, ForkingMixIn):
pass
```
#定制類
類似\_\_slots\_\_這種形如\_\_xxx\_\_的變量或者函數(shù)名就要注意,這些在Python中是有特殊用途的厢塘。例如\_\_len\_\_()方法是為了能讓class作用于len()函數(shù)茶没。
- ## \_\_str__
def str(self):
return 'Student object (name: %s)' % self.name
在類中寫(xiě)這段 使用print進(jìn)行打印輸出的時(shí)候就會(huì)按照格式顯示,但是如果不用print打印則不會(huì)按照格式輸出
這是因?yàn)橹苯语@示變量調(diào)用的不是\_\_str\_\_而是\_\_repr\_\_()來(lái)返回用戶看到的字符串,而\_\_repr\_\_()返回的是程序開(kāi)發(fā)者所看到的字符串,也就是說(shuō)\_\_repr\_\_()是為調(diào)試服務(wù)的.
解決辦法是在寫(xiě)一個(gè)\_\_repr\_\_()方法,但是由于\_\_str\_\_和\_\_repr\_\_()方法通常一樣,所以簡(jiǎn)單的寫(xiě)法為
```class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__
```
- ## \_\_iter\_\_
如果一個(gè)類想被用于for...in循環(huán),類似list和tuple.那就必須實(shí)現(xiàn)一個(gè)\_\_iter\_\_()方法,該方法的返回值是一個(gè)可迭代的對(duì)象,然后Python的for循環(huán)就會(huì)不斷調(diào)用\_\_next\_\_()方法拿到循環(huán)的下一個(gè)值,知道遇到stopIteration拋出異常為止
```
#斐波那契數(shù)列
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1 # 初始化兩個(gè)計(jì)數(shù)器a肌幽,b
def __iter__(self):
return self # 實(shí)例本身就是迭代對(duì)象,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b # 計(jì)算下一個(gè)值
if self.a > 100000: # 退出循環(huán)的條件
raise StopIteration();
return self.a # 返回下一個(gè)值
-
__getitem__
實(shí)現(xiàn)了__iter__方法之后,雖然能夠使用for循環(huán)進(jìn)行迭代,但是并不能像list似的使用下標(biāo)來(lái)訪問(wèn)其中的元素,若要實(shí)現(xiàn)該功能則需要實(shí)現(xiàn)__getitem__()方法
class Fib(object):
def __getitem__(self, n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
這樣做雖然可以使用下標(biāo)進(jìn)行訪問(wèn)了,但是對(duì)于list(range(10))[2:9]這樣的切片方法卻行不通,原因是getitem()傳入的參數(shù)可能是一個(gè)int礁叔,也可能是一個(gè)切片對(duì)象slice牍颈,這個(gè)時(shí)候就需要就傳入的參數(shù)進(jìn)行判斷了
-
__getattr__
使用Python的另一個(gè)機(jī)制是寫(xiě)一個(gè)getattr()方法,動(dòng)態(tài)返回一個(gè)屬性琅关≈笏辏可以避免因?yàn)檎{(diào)用不存在的屬性出現(xiàn)的錯(cuò)誤.這個(gè)方法只有在沒(méi)有找到屬性的情況下才會(huì)調(diào)用, 這個(gè)方法同樣可以返回一個(gè)函數(shù).
class Student(object):
def __init__(self):
self.name = 'Michael'
def __getattr__(self, attr):
if attr=='score':
return 99
# 返回一個(gè)函數(shù)
class Student(object):
def __getattr__(self, attr):
if attr=='age':
return lambda: 25
這樣在調(diào)用Student類的score這個(gè)不存在的屬性的時(shí)候就不會(huì)出現(xiàn)錯(cuò)誤信息而是返回99這個(gè)數(shù)
- __call__
一個(gè)對(duì)象實(shí)例可以有自己的屬性和方法,當(dāng)我們調(diào)用實(shí)例方法時(shí)使用__call__可以直接在實(shí)例本身上調(diào)用方法.
任何類,只需要定義一個(gè)__call__()方法涣易,就可以直接對(duì)實(shí)例進(jìn)行調(diào)用.
class Student(object):
def __init__(self, name):
self.name = name
def __call__(self):
print('My name is %s.' % self.name)
# 調(diào)用方法:
s = Student('Joe')
s() # self參數(shù)不要傳入
My name is Joe.
枚舉類
- Python中的枚舉類型需要先從enum模塊中引入Enum類.
然后創(chuàng)建一個(gè)枚舉
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
如上所示即獲得了Month類型的枚舉,可以使用Month.Jan, Month.Feb 這種類型進(jìn)行訪問(wèn), 也可以使用forin來(lái)遍歷
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value)
member.value是自動(dòng)給枚舉賦值的,賦值從1開(kāi)始
- 如果要精確的控制枚舉類型, 可以從Enum派生出自定義類.
from enum import Enum, unique
@unique
class Weekday(Enum):
Sun = 0 # Sun的value被設(shè)定為0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
其中裝飾器@unique的作用是檢查name所對(duì)應(yīng)的value值是否唯一
-
訪問(wèn)方式有很多
例如:
Weekday['Tue']
Weekday(1)
Weekday.Sun
Weekday.Tue.value
......
元類
-
type()
Python是一門(mén)動(dòng)態(tài)語(yǔ)言,他所有的類和方法都不是在編譯的時(shí)候創(chuàng)建的,而是在運(yùn)行的時(shí)候創(chuàng)建的.
type()既可以返回一個(gè)class類型,也使用type()可以在運(yùn)行時(shí)動(dòng)態(tài)的創(chuàng)建一個(gè)class.無(wú)需經(jīng)過(guò)
class name(object):
來(lái)定義- 首先定義一個(gè)方法
def fn(self, name = 'world'): print('Hello %s' % name)
- 使用type()方法創(chuàng)建一個(gè)class
Hello = type('Hello', (object, ), dict(hello = fn))
- type()的三個(gè)參數(shù)
1.第一個(gè)參數(shù)是定義的class的名字
2.第二個(gè)參數(shù)是繼承的類,這是一個(gè)tuple.如果不是多繼承的話,需要傳入一個(gè)單元素的元組(object,)
3.第三個(gè)參數(shù)是方法名與函數(shù)的綁定,將在類外面定義的函數(shù)綁定到類的方法上