類和對象的關系就像數據結構和數據的關系一樣,類規定了存儲什麼數據,對象用來實際存儲數據
"""
1.類的定義和構造
2.類的方法(函數) 構造 析構
一般函數的第一個參數是實例對象名,代之需要調用函數的對象,傳參時不傳入
3.類的屬性(成員) 公有 私有
"""
"""
python 不存在無法訪問的私有屬性
如何保持封裝的封閉性
"""
class student:
__age=0#私有成員
name=""#公有成員
Id=""
def __init__(self,name,age,Id):#構造函數
self.name=name
self.Id=Id
self.__age=age
print("%s同學的信息構造完成"%self.name)
def __del__(self):#析構函數
print("%s同學的信息被刪除"%self.name)
def printf(self):#查看信息
print("%s同學的年齡為:%s\n學號為:%s"%(self.name,self.__age,self.Id))
if __name__ == '__main__':
#信息構造
stu1=student("李華","21","20212203")
stu2=student("李明","20","20212204")
stu3=student("李強","21","20212201")
#信息查看
stu1.printf()
stu2.printf()
stu3.printf()
#在類外調用私有成員要加類名限制(私有成員在類外也是可以定義的)
print("%s同學的年齡為:%s"%(stu1.name,stu1._student__age))
#信息刪除
stu4=stu1
del stu1#對象信息備份在stu4
del stu2
del stu3
""" 這裡的復數對象要當作字符串輸出,定義__str__方法實現 """
class complex:
def __init__(self,real,image):
self.real=real
self.image=image
def __str__(self):
if self.image >=0:
return str(self.real)+'+'+str(self.image)+'i'
else:
return str(self.real)+str(self.image)+'i'
''' def __str__(self): if self.image >= 0: return '{}+{}i'.format(self.real,self.image) else: return '{}{}i'.format(self.real,self.image) '''
c=complex(-1,2.3)
print(c)
c1=c=complex(1,-2.3)
print(c1)
""" 定義一個學生類,判斷一個同學的成績是否大於另一個 感覺有點類似於C++運算符重載 """
class student:
def __init__(self,name,score):
self.score=score
self.name=name
def __gt__(self,other):
return self.score>=other.score
stu1=student('李華',78)
stu2=student('李明',80)
print('李明的成績高於李華:',stu2.score>stu1.score)
“當看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這只鳥就可以被稱為鴨子。”
在鴨子類型中,關注點在於對象的行為,能作什麼;而不是關注對象所屬的類型。
鴨子類型使得有相同功能的不同類也能實現多態,這是C++不具備的
""" 在鴨子類型中,關注點在於對象的行為,能作什麼; 而不是關注對象所屬的類型。 """
class person:
def __init__(self,name,age):
self.name=name
self.age=age
def printt(self):
print('%s的年齡為%d'%(self.name,self.age))
class Dog:
def __init__(self,name,weight):
self.name=name
self.weight=weight
def printt(self):
print('狗狗%s的體重為%d'%(self.name,self.weight))
def printt(tmp):
tmp.printt()
c1=person('李華',12)
c2=Dog('喬治', 100)
printt(c1)
printt(c2)
1.單繼承與多繼承
2.方法重寫: 方法重寫就是在繼承中子類對於父類已有的功能進行重寫,可以通過鴨子類型實現多態
3.super: 獲取當前類父類的代理對象(一般用於子類構造函數對父類元素賦值)
""" 1.單繼承與多繼承 2.方法重寫: 方法重寫就是在繼承中子類對於父類已有的功能進行重寫,可以通過父類的引用實現多態 3.super: 獲取當前類父類的代理對象(一般用於子類構造函數對父類元素賦值) 學生 人——> ——> 助教 老師 """
class person:
def __init__(self,sex,name):
self.sex=sex;
self.name=name
def Printinfo(self):
print('{}的性別為{}'.format(self.name,self.sex))
class student(person):
def __init__(self,sex,name,sno):
super().__init__(sex,name)
self.sno=sno
def Printinfo(self):
print('{}的性別為{},學號為{}'.format(self.name,self.sex,self.sno))
class teacher(person):
def __init__(self,sex,name,tno):
super().__init__(sex,name)
self.tno=tno
def Printinfo(self):
print('{}的性別為{},教師號為{}'.format(self.name,self.sex,self.tno))
class assistant(teacher,person):
pass
def Printinfo(tem):
tem.Printinfo()
c1=teacher('男', '李華', '11230')
c2=student('女', '李梅', '12345')
c3=person('男', '李強')
Printinfo(c1)
Printinfo(c2)
Printinfo(c3)
暫時不知python怎麼消除多繼承二義性,對於助教類先不擴展
1.isinstance 判斷一個類是否是指定類或者是指定類的子類
2.issubclass 判斷一個類是否是另一個類的子類
3.type()函數 獲取一個對象所屬的類
""" 1.isinstance 判斷一個類是否是指定類或者是指定類的子類 2.issubclass 判斷一個類是否是另一個類的子類 3.type()函數 獲取一個對象所屬的類 """
class person:
def __init__(self,sex,name):
self.sex=sex;
self.name=name
class student(person):
def __init__(self,sex,name,sno):
super().__init__(sex,name)
self.sno=sno
class flower:
def __init__(self,colour):
self.colour=colour
c1=person('男','李明')
c2=student('女','李華','12345')
c3=flower('red')
print(type(c1))
print(type(c2))
print(type(c3))
print('flower類是person類的子類:',issubclass(flower,person))
print('flower類是person類的子類:',issubclass(student,person))
當一個屬性是類所有而不是每個對象所擁有的時候要定義為類方法或靜態方法,二者的區別是靜態方法不用 寫self,即靜態方法並不綁定對象,也就無法修改對象的值
# -*- coding: utf-8 -*-
""" 類方法與靜態方法:當類的一個方法是類所有而不是對象的方法時,可以定義為類方法或靜態方法 類方法:@calssmethon 綁定了對象 靜態方法:@staticmethod 未綁定對象 未綁定對象無法修改對象的值 """
class complex:
def __init__(self,real=0,image=0):
self.real=real
self.image=image
@classmethod#類方法
def add1(cls,c1,c2):
c=complex()
c2.real=3
c.real=c1.real+c2.real
c.image=c1.image+c2.image
if c.image >=0:
return str(c.real)+'+'+str(c.image)+'i'
else:
return str(c.real)+str(c.image)+'i'
@staticmethod#靜態方法
def add2(c1,c2):
c=complex()
#c2.real=1 在靜態方法裡修改對象的值無法修改成功
c.real=c1.real+c2.real
c.image=c1.image+c2.image
if c.image >=0:
return str(c.real)+'+'+str(c.image)+'i'
else:
return str(c.real)+str(c.image)+'i'
c1=complex(1,2)
c2=complex(2,3)
c3=complex.add1(c1,c2)
print(c3)
c4=complex.add1(c1,c2)
print(c4)
動態擴展類:在不修改原有類的情況下動態的為類添加新的屬性或方法
1.綁定新方法:需要使用 types 模塊的 MethodType 方法
from types import Mythodtype
2.綁定新屬性:
可以使用__slots__函數限制可綁定的新屬性
""" 動態擴展類:在不修改原有類的情況下動態的為類添加新的屬性或方法 1.綁定新方法:需要使用 types 模塊的 MethodType 方法 from types import Mythodtype 2.綁定新屬性: 可以使用__slots__函數限制可綁定的新屬性 """
from types import MethodType
class person:
def __init__(self,sex,name):
self.sex=sex;
self.name=name
def printname(self):
print('%s'%self.name)
def printsex(self):
print('%s'%self.sex)
# 注意 __name__ 的用法
if __name__ == '__main__':
person.printname=printname
p1=person('男','李強')
p2=person('女','李華')
p1.printsex=MethodType(printsex,p1)
#給person類綁定printname方法,給對象p1綁定printsex
p1.printname()
p2.printname()
p1.printsex()
#p2.printsex() p2 無 printsex 這個功能
class person:
__slots__=('name')
class teacher(person):
__slots__=('tno')
class student(person):
pass
# 子類有限制會繼承父類的限制,子類無限制不繼承父類限制
if __name__ == '__main__':
p1=person()
p1.name='李華'
t1=teacher()
t1.name='李強'
t1.tno='123'
#t1.sno='122' t1 不允許擴展 sno 會報錯
print('%s'%t1.tno)
s1=student()
s1.name='麗麗'
s1.tno='123'
s1.height='12'
print('%s'%s1.height)
# student類無限制,隨意擴展
使用 __del__ 方法時 , 當要釋放一個對象的內存時
會先檢查一個對象的引用計數,只有 count = 0 時才會釋放內存
""" 使用 __del__ 方法時 , 當要釋放一個對象的內存時 會先檢查一個對象的引用計數,只有 count = 0 時才會釋放內存 我們可以通過 sys 模塊中的 getrefcount 來獲取一個對象的引用計數 導致引用計數+1的情況: 1.對象被創建 2.對象被引用 3.對象作為參數被傳入到一個函數中 4.對象作為元素被存儲在容器中 導致引用計數-1的情況: 1.對象的別名被顯式銷毀 2.對象的別名被賦給了新的對象 3.一個對象離開了它的作用域(如一個函數執行完後,它裡面的局部變量) 4.對象所存在的容器被銷毀,或從容器中刪除了對象 """
import sys
class people:
def __del__(self):
print("對象已被銷毀")
pass
p1=people() #count = 1
count=sys.getrefcount(p1) # 對象作為參數被傳到了一個函數中 count = 2
print(count)
p2=p1 #對象被引用 count = 3
count=sys.getrefcount(p1)
print(count)
del p2 #count = 1
print("-------1--------")
del p1 #count = 0
print("-------2--------")