記住一句話:類是模板,而實例則是根據類建立的對象。html
初學時對類的理解是從類的字面上,能夠片面的認爲它是一個種類,它是類似特徵的抽像,也就是類似的東西,能夠把類似特徵的事務抽象成一個類。(事務能夠是具體的物體或行爲)python
以圓爲例,圓是具備圓周率(pi)和半徑(r)兩個類似特徵的屬性。根據類似特徵抽象出圓類,每一個圓的半徑能夠不一樣,那麼半徑能夠做爲圓的實例屬性;而每一個圓的圓周率pi是相同的,那麼圓周率pi就能夠做爲類屬性,這樣就定義出了一個圓類。而咱們要知道圓的面積,周長等能夠經過類方法計算出來。編程
(看完整篇文章,仍是對類不理解,回過頭在來看這部分,對照列子多理解。)數據結構
零散代碼(代碼塊)-->函數(方法)-->類-->模塊(文件)
類:表示抽象(模糊)的事物
對象:表示具體(清晰)的事物編程語言
使用 class 語句來建立一個新類,class 以後爲類的名稱並以冒號結尾:ide
class ClassName: '類的幫助信息' #類文檔字符串 class_suite #類體
類的幫助信息能夠經過ClassName.doc查看。函數
class_suite 由類成員,方法,數據屬性組成。ui
描述人類的文件
類的結構:
一、動態的行爲(動詞):speak、sing
二、靜態的屬性(名詞):gender、user_name
(1)全局:在類中的任何地方都能使用
(2)局部:只可以在方法內部使用
使用類:
實例化對象:對象名 = 類名 ( 參數【可選的】)翻譯
class Human(): """模擬人類""" def __init__(self, sex, name): """初始化屬性:gender和user_name""" self.gender = sex self.user_name = name def speak(self): """模擬人類說話""" print(self.user_name.title() + "正在說話。") def sing(self): """模擬人類唱歌""" print(self.user_name.title() + "正在唱歌。")
empCount
變量是一個類變量,它的值將在這個類的全部實例之間共享。你能夠在內部類或外部類使用 Employee.empCount
訪問。__init__()
方法是一種特殊的方法,被稱爲類的構造函數或初始化方法,當建立了這個類的實例時就會調用該方法self
表明類的實例,self
在定義類的方法時是必須有的,雖然在調用時沒必要傳入相應的參數。# 使用類 man = Human('男','xgp') man.speak() lz = Human('男','kk') lz.sing()
class Pet(): def __init__(self,sex,strain): """給屬性賦初始值(默認值)""" self.nick_name = '咪咪' self.gender = sex self.stain = strain cat = Pet('公','土貓') # 修改初始值 cat.nick_name = '妙妙' print(cat.nick_name)
妙妙
類的方法與普通的函數只有一個特別的區別——它們必須有一個額外的第一個參數名稱
, 按照慣例它的名稱是 self。設計
class Test: def prt(self): print(self) print(self.__class__) t = Test() t.prt()
<__main__.Test instance at 0x10d066878> __main__.Test
從執行結果能夠很明顯的看出,self 表明的是類的實例,表明當前對象的地址,而 self.__class__
則指向類。
self 不是 python 關鍵字,咱們把他換成 runoob
也是能夠正常執行的:
class Test: def prt(runoob): print(runoob) print(runoob.__class__) t = Test() t.prt()
<__main__.Test instance at 0x10d066878> __main__.Test
實例化類其餘編程語言中通常用關鍵字 new,可是在 Python 中並無這個關鍵字,類的實例化相似函數調用方式。
如下使用類的名稱 Dn
來實例化,並經過 __init__
方法接收參數。
""" 小名和小紅各自買了一臺筆記本電腦, 其中小名的電腦品牌是聯想, CPU8核, 512G固態硬盤,雙飛燕鼠標 省紅的電腦品牌是機械師, CPU4核, 256G固態硬盤+1T普通硬盤,機械師鼠標 使用面向對象的思惟,編寫代碼完成以 上描述。 """ class Dn(): def __init__(self,name,brand,cpu,disk,mouse): self.nice_name = name self.nice_pp = brand self.nice_cpu = cpu self.nice_disk = disk self.nice_mouse = mouse def xgp(self): print(self.nice_name + '的電腦配置:「' + '品牌:' + self.nice_pp + ',' + 'cpu:' +self.nice_cpu + ',' + '硬盤:' +self.nice_disk + ',' + '鼠標:' + self.nice_mouse + ',' + '」。') # 可使用點號 . 來訪問對象的屬性。使用以下類的名稱訪問類變量 Dn1 = Dn('小名','聯想','8核','512固態硬盤','雙飛燕') Dn1.xgp() Dn2 = Dn('小米','機械師','4核','256G固態硬盤+1T普通硬盤','機械師鼠標') Dn2.xgp()
小名的電腦配置:「品牌:聯想,cpu:8核,固態硬盤:512固態硬盤,鼠標:雙飛燕」。 小名的電腦配置:「品牌:機械師,cpu:4核,固態硬盤:256G固態硬盤,機械硬盤1T普通硬盤,鼠標:機械師鼠標」。
面向對象的編程帶來的主要好處之一是代碼的重用,實現這種重用的方法之一是經過繼承機制。
經過繼承建立的新類稱爲子類
或派生類,被繼承的類稱爲基類
、父類
或超類
。
繼承語法
class 派生類名(基類名) ...
在python中繼承中的一些特色:
若是在繼承元組中列了一個以上的類,那麼它就被稱做"多重繼承" 。
派生類的聲明,與他們的父類相似,繼承的基類列表跟在類名以後,以下所示:
class SubClassName (ParentClass1[, ParentClass2, ...]): ...
class Parent: # 定義父類 parentAttr = 100 def __init__(self): print ("調用父類構造函數") def parentMethod(self): print('調用父類方法') def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print ("父類屬性 :", Parent.parentAttr) class Child(Parent): # 定義子類 def __init__(self): print ("調用子類構造方法") def childMethod(self): print ('調用子類方法') c = Child() # 實例化子類 c.childMethod() # 調用子類的方法 c.parentMethod() # 調用父類方法 c.setAttr(200) # 再次調用父類的方法 - 設置屬性值 c.getAttr() # 再次調用父類的方法 - 獲取屬性值
調用子類構造方法 調用子類方法 調用父類方法 父類屬性 : 200
""" 小名和小紅各自買了一臺筆記本電腦, 其中小名的電腦品牌是聯想, CPU8核, 512G固態硬盤,雙飛燕鼠標 省紅的電腦品牌是機械師, CPU4核, 256G固態硬盤+1T普通硬盤,機械師鼠標 使用面向對象的思惟,編寫代碼完成以 上描述。 """ class Dn(): def __init__(self,brand,cpu,disk,mouse): self.nice_pp = brand self.nice_cpu = cpu self.nice_disk = disk self.nice_mouse = mouse # 繼承:共享某個類的代碼 class XiaoMing(Dn): def __init__(self,brand,cpu,disk,mouse): super().__init__(brand,cpu,disk,mouse) def xgp(self,name): print(name + '的電腦配置:「' + '品牌:' + self.nice_pp + ',' + 'cpu:' +self.nice_cpu + ',' + '固態硬盤:' +self.nice_disk + ',' + '鼠標:' + self.nice_mouse + '」。') class XiaoHong(Dn): def __init__(self,brand,cpu,disk,sim_disk,mouse): self.sim_disk = sim_disk super() . __init__(brand,cpu,disk,mouse) def wsd(self,name): print(name + '的電腦配置:「' + '品牌:' + self.nice_pp + ',' + 'cpu:' + self.nice_cpu + ',' + '固態硬盤:' + self.nice_disk + ',' + '機械硬盤' + self.sim_disk + ',' + '鼠標:' + self.nice_mouse + '」。') xiaoming = XiaoMing('聯想','8核','512固態硬盤','雙飛燕') xiaoming.xgp('小名') xiaohong = XiaoHong('機械師','4核','256G固態硬盤','1T普通硬盤','機械師鼠標') xiaohong.wsd('小名')
小名的電腦配置:「品牌:聯想,cpu:8核,固態硬盤:512固態硬盤,鼠標:雙飛燕」。 小名的電腦配置:「品牌:機械師,cpu:4核,固態硬盤:256G固態硬盤,機械硬盤1T普通硬盤,鼠標:機械師鼠標」。
class Empoyee(): """員工類""" def __init__(self,name,years_old,money): """初始化普通員工屬性""" self.user_name = name self.user_years_old = years_old self.user_money = money def say_hi(self): """模擬員工自我介紹的方法""" print('我叫'+self.user_name +',工齡' + self.user_years_old +'年,年工資爲' + self.user_money +'元。' ) class SE(Empoyee): def __init__(self,name,years_old,money): super().__init__(name,years_old,money) def say_hi(self): """模擬員工自我介紹的方法""" print('我叫'+self.user_name +',工齡' + self.user_years_old +'年,年工資爲' + self.user_money +'元。' ) class PM(Empoyee): def __init__(self,name,years_old,money,bonus): super().__init__(name,years_old,money) # 編寫子類特有的屬性 self.pm_bonus = bonus def say_hi(self): """模擬項目經理自我介紹的方法""" print('我叫'+self.user_name +',工齡' + self.user_years_old +'年,月工資爲' + self.user_money +'元,' + '管理獎金' + self.pm_bonus + '元。' ) class CTO(Empoyee): def __init__(self,name,years_old,money,bonus,annual_bonus): super().__init__(name,years_old,money) self.cto_bonus = bonus self.cto_annual_bonus = annual_bonus def say_hi(self): """模擬項目經理自我介紹的方法""" print('我叫'+self.user_name +',工齡' + self.user_years_old +'年,月工資爲' + self.user_money +'元,' + '管理獎金' + self.cto_bonus + '元,' + '年終獎' + self.cto_annual_bonus + '元。' ) # 使用類:實例化對象 se = SE('xgp','4','8k') se.say_hi() pm = PM('wsd','6','10000','5000') pm.say_hi() cto = CTO('xgp','10','30000','6000','12000') cto.say_hi()
我叫xgp,工齡4年,年工資爲8k元。 我叫wsd,工齡6年,月工資爲10000元,管理獎金5000元。 我叫xgp,工齡10年,月工資爲30000元,管理獎金6000元,年終獎12000元。
__dict__
: 類的屬性(包含一個字典,由類的數據屬性組成)__name__
: 類名__module__
: 類定義所在的模塊(類的全名是'__main__.className
',若是類位於一個導入模塊mymod中,那麼className.__module__
等於 mymod)__bases__
: 類的全部父類構成元素(包含了一個由全部父類組成的元組)#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: '全部員工的基類' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
Employee.__doc__: 全部員工的基類 Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: () Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}
Python 使用了引用計數這一簡單技術來跟蹤和回收垃圾。
在 Python 內部記錄着全部使用中的對象各有多少引用。
一個內部跟蹤變量,稱爲一個引用計數器。
當對象被建立時, 就建立了一個引用計數, 當這個對象再也不須要時, 也就是說, 這個對象的引用計數變爲0 時, 它被垃圾回收。可是回收不是"當即"的, 由解釋器在適當的時機,將垃圾對象佔用的內存空間回收。
a = 40 # 建立對象 <40> b = a # 增長引用, <40> 的計數 c = [b] # 增長引用. <40> 的計數 del a # 減小引用 <40> 的計數 b = 100 # 減小引用 <40> 的計數 c[0] = -1 # 減小引用 <40> 的計數
垃圾回收機制不只針對引用計數爲0的對象,一樣也能夠處理循環引用的狀況。循環引用指的是,兩個對象相互引用,可是沒有其餘變量引用他們。這種狀況下,僅使用引用計數是不夠的。Python 的垃圾收集器其實是一個引用計數器和一個循環垃圾收集器。做爲引用計數的補充, 垃圾收集器也會留心被分配的總量很大(及未經過引用計數銷燬的那些)的對象。 在這種狀況下, 解釋器會暫停下來, 試圖清理全部未引用的循環。
析構函數 __del__
,__del__
在對象銷燬的時候被調用,當對象再也不被使用時,__del__
方法運行:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print class_name, "銷燬" pt1 = Point() pt2 = pt1 pt3 = pt1 print id(pt1), id(pt2), id(pt3) # 打印對象的id del pt1 del pt2 del pt3
3083401324 3083401324 3083401324 Point 銷燬
注意:一般你須要在單獨的文件中定義一個類
參數的傳遞圖,翻譯與pythoncentral網