小甲魚Python筆記(類)


類和對象

類的構造方法 def __init__():

1 class People:
2     def __init__(self,name): 3 self.name = name

注意:在構造方法中的變量不用再次聲明,必須有self,創建類的對象是用=

 

類的私有成員

讓方法或者類變為私有,只要在它的名字前加上雙下划線

1 class People:
2     __name = 'laowang'
3     def getname(self): 4 return self.__name

 

注意:類的私有成員可以通過方法訪問,也可以通過   _類名__私有成員這種格式來訪問

 

類的繼承

class 子類(父類、基類、超類)

在繼承構造函數的過程中,可以用以下兩個方法,推薦方法2:

(1)調用未綁定的父類構造方法

1 class People:
2     def __init__(self): 3 self.name = 'aa' 4 class Student(People): 5 def __init__(self): 6 People.__init__(self) 7 self.son = 20

(2)使用super

class People:
    def __init__(self): self.name = 'aa' class Student(People): def __init__(self): super().__init__() self.son = 20

 super可以不帶任何參數,但是當父類中有參數傳入,super后的__init__要加上參數而且不能加上self

1 class People:
2     def __init__(self,name): 3 self.name = name 4 class Student(People): 5 def __init__(self,name,sno): 6 super().__init__(name) 7 self.name = name 8 self.sno = sno

 

類的組合

類之間沒用明顯繼承關系可以用組合,比如一個電話簿的類由電話和地址類組合起來:

 1 class Tel:
 2     def __init__(self,x): 3 self.info = x 4 5 class Add: 6 def __init__(self,y): 7 self.info = y 8 9 class Notebook: 10 def __init__(self,x,y): 11 self.tel = Tel(x) 12 self.add = Add(y) 13 def print_info(self): 14 print("Tel:%s\nAdd:%s" %(self.tel.info,self.add.info))

 

類 類對象 實例對象

類對象就像C++中的static變量,一個對象有了實例對象后就將類對象的值覆蓋了

屬性名如果和方法名相同,屬性會覆蓋方法 

 

綁定

對象.__dict__返回對象擁有的屬性

對象調用后方法綁定到實例對象上del類后,a的方法還是存在的,因為A的方法和屬性都是static,程序退出前不會消失

 

一些和類相關的BIF

issubclass(class, classinfo)


isinstance(object, classinfo)


hasattr(object, name)  注意第二個參數要用字符串格式


getattr(object, name[, default])


setattr(object, name, value)  設置屬性

delattr(object, name)     刪除屬性,屬性不存在拋出異常 

property()

為什么用property

首先一個實例化的對象可以進行直接的賦值和修改,如c.age = 10,但是這樣沒法做參數檢查,我就可以讓c.age = 1000,這顯然是不合理的

於是,用方法可以對參數進行檢查,可以用c.setage(66)來設置年齡,但是這樣就不方便了

函數property的基本功能就是把類中的方法當作屬性來訪問,為什么用方法來操作

 1 class C:
 2     def __init__(self,age = 10):
 3         self.age = age
 4     def getage(self):
 5         return self.age
 6     def setage(self,value):
 7         if 0 <= value <= 120:
 8             self.age = value
 9         else:
10             print("年齡非法")
11     def delage(self):
12         del self.age
13     x = property(getage,setage,delage)

 

 

魔法方法

(1)構造和析構

魔法方法總是被雙下划線包圍,它們總能在適當的時候自動被調用

__init__(self)  不能有返回值

__new__(cls[,])  返回一個類對象,python自動調用,一般不需要重寫,依照Python官方文檔的說法,__new__方法主要是當你繼承一些不可變的class時(比如int, str, tuple), 提供給你一個自定義這些類的實例化過程的途徑。

__del__(self)   del一個對象的時候被調用

 

(2)屬性和訪問

__getattr__(self,name)  定義當用戶試圖獲取一個不存在的屬性時的行為

__getattribute__(self,name)  定義當該類屬性被訪問時的行為

__setattr__(self,name,value)  定義當一個屬性被設置的行為

__delattr__(self,name)  定義當一個屬性被刪除的行為

程序1:查看屬性方法何時被調用

 1 class C:
 2     def __getattribute__(self,name):
 3         print("getattribute")
 4         return super().__getattribute__(name)
 5     def __getattr__(self,name):
 6         print("getattr")
 7     def __setattr__(self,name,value):
 8         print("setattr")
 9         super().__setattr__(name,value)
10     def __delattr__(self,name):
11         print("delattr")
12         super().__delattr__(name)

 

 

當訪問一個不存在的屬性,就調用先調用getattribute,在調用getattr,訪問存在的屬性調用getattribut后顯示其值

 

程序2:寫一個矩形類,默認有寬高兩個屬性,如果給一個叫square的屬性復制,那么說明這是一個正方形(Python基礎教程151,小甲魚45)

 1 class Rectangle:
 2     def __init__(self,width = 0,height = 0):
 3         self.width = width
 4         self.height = height
 5     def __setattr__(self,name,value):
 6         if name == "square":
 7             self.width = value
 8             self.height = value
 9         else:
10             self.__dict__[name] = value
11     def getarea(self):
12         return self.width * self.height

 

 

 

(3)描述符(property的原理)

 描述符就是將某種特殊類型的類的實例指派給另一個類的屬性

__get__(self,instance,owner)  用於訪問屬性,它返回屬性的值

__set__(self,instance,value)   將在屬性分配操作中調用,不返回任何內容

__delete__(self,instance)    控制刪除操作,不返回任何內容

 

(4)定制容器(Python基礎教程144,小甲魚47)

定制的容器對象是不可變的,需要前兩個魔法方法;可變的需要4個魔法方法

1. 如果說你希望定制的容器是不可變的話,你只需要定義 __len__() 和 __getitem__() 方法。

2. 如果你希望定制的容器是可變的話,除了 __len__() 和 __getitem__() 方法,你還需要定義 __setitem__() 和__delitem__() 兩個方法。

 

迭代器

BIF:iter()返回一個迭代器,next()返回下一個元素

對應的魔法方法__iter__()   __next__()

用迭代器寫的裴波那切數列:

 1 class Fibs:
 2     def __init__(self,n = 10):
 3         self.a = 0
 4         self.b = 1
 5         self.n = n
 6     def __iter__(self):
 7         return self
 8     def __next__(self):
 9         self.a,self.b = self.b,self.a+self.b
10         if self.a > self.n:
11             raise StopIteration
12         return self.a

 

生成器

生成器是迭代器的一種實現

用yield或者圓括號

yield

圓括號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM