python學習(十六)——多型、封裝、反射、、動態匯入模組、類內建attr方法
阿新 • • 發佈:2018-12-16
一、多型
# 不同的例項呼叫同樣的方法,產生不同的結果 # 多型來自繼承 class H2O: def __init__(self,name,temperature): self.name=name self.temperature=temperature def turn_ice(self): if self.temperature < 0: print('[%s]溫度太低結冰了' %self.name) elif self.temperature > 0 and self.temperature < 100: print('[%s]液化成水' %self.name) elif self.temperature > 100: print('[%s]溫度太高變成了水蒸氣' %self.name) def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(self): pass class Water(H2O): pass class Ice(H2O): pass class Steam(H2O): pass w1=Water('水',25) i1=Ice('冰',-20) s1=Steam('蒸汽',3000) # w1.turn_ice() # i1.turn_ice() # s1.turn_ice() def func(obj): obj.turn_ice() func(w1) #---->w1.turn_ice() func(i1) #---->i1.turn_ice() # def func(obj): # obj.turn_ice() # # func(w1) # func(i1) # func(s1)
二、封裝
# 第一層封裝:類就是麻袋,本身是一種封裝 # 第二層封裝: _ (單下劃線)對外部隱藏,只能內部使用--- 僅僅是約定,仍然可以訪問到 # __ (雙下劃線)python會對其重新命名為--- _People__star # 第三層封裝:只在內部使用,外部無法呼叫到,並且提供一個介面 #----------------------------封裝一-------------------------------- class People: __star='earth111111111111' __star1='earth111111111111' __star2='earth111111111111' __star3='earth111111111111' def __init__(self,id,name,age,salary): print('----->',self.__star) self.id=id self.name=name self.age=age self.salary=salary def get_id(self): print('我是私有方法啊,我找到的id是[%s]' %self.id) #訪問函式 def get_star(self): print(self.__star) p1=People('123123123123','alex','18',100000000) # print(p1.__star) print(People.__dict__) # print(p1.__star) print(p1._People__star) # # p1.get_star() p1.get_star() #----------------------------封裝示例2------------------------------------------ class Room: def __init__(self,name,owner,width,length,high): self.name=name self.owner=owner self.__width=width # 最開始的時候不要用下劃線開頭 self.__length=length self.__high=high def tell_area(self): # 此時我們想求的是面積 --介面函式(不推薦) return self.__width * self.__length *self.__high def tell_width(self): return self.__width r1=Room('衛生間','alex',100,100,10000) # arear=r1.__width * r1.__length print(r1.tell_area())
三、反射\自省
1、四個自省函式
# 類和物件都適用 # 判斷object中有沒有一個叫name字串對應的方法或函式 hasattr(object, name) # 找名字或者方法函式,default是判斷為False時輸出資訊 hasattr(object, name, default) # 修改 setattr(x, y, v) # 刪除 delattr(x, y) class BlackMedium: feture='Ugly' def __init__(self,name,addr): self.name=name self.addr=addr def sell_hourse(self): print('【%s】 正在賣房子' %self.name) def rent_hourse(self): print('【%s】 正在租房子' % self.name) b1=BlackMedium('abc','rb') print(hasattr(b1,'name'))
2、反射的使用
# 可插拔式設計
#--------------------------使用者------------------------------
from ftp_client import FtpClient
f1=FtpClient('1.1.1.1')
# f1.put()
if hasattr(f1,'put'):
func_get=getattr(f1,'put')
func_get()
else:
print('其他的邏輯')
#-------------------------客戶端-------------------------------
class FtpClient:
'ftp客戶端,但是還沒有實現具體的功能'
def __init__(self,addr):
print('正在連線伺服器[%s]' %addr)
self.addr=addr
# 後面實現的功能
# def put(self):
# print('正在上傳檔案')
三、動態匯入模組
module_t=__import__('m1.t') # 匯入模組只匯入了m1
print(module_t)
module_t.t.test1()
import importlib
m=importlib.import_module('m1.t') #匯入例如m1.t
print(m)
m.test1()
m._test2()
#---------------------當匯入全部時,_開頭的不能匯入---------------------
from m1.t import *
# from m1.t import test1,_test2
test1()
_test2() #出錯
四、類的內建attr屬性
# 不重寫就用預設的,重寫就用重寫的
class Foo:
x = 1
def __init__(self, y):
self.y = y
def __getattr__(self, item): # 用處較多
print('執行__getattr__')
def __delattr__(self, item):
print('刪除操作')
self.__dict.pop(item)
def __setattr__(self, key, value):
print('__setattr__執行')
# self.key = value 無限遞迴,錯誤
self.__dict__[key] = value
f1 = Foo(10)
# 呼叫一個不存在的屬性時執行
print(f1.y)
print(getattr(f1, 'y')) # len(str)--->str.__len__()
f1.asdasd # 執行__getattr__
# 刪除時執行
del f1.y
print(f1.__dict__)# 新增成功
五、二次加工標準型別(包裝、授權)
#------------------------------包裝------------------------------------
class List(list):
def append(self, p_object):
if type(p_object) is str:
# self.append(p_object)
super().append(p_object)
else:
print('只能新增字串型別')
def show_midlle(self):
mid_index=int(len(self)/2)
return self[mid_index]
# l2=list('hell oworld')
# print(l2,type(l2))
l1=List('helloworld')
# print(l1,type(l1))
# print(l1.show_midlle())
l1.append(1111111111111111111111)
l1.append('SB')
print(l1)
#-----------------------------------授權--------------------------------
# 通過__getattribute__實現
import time
class FileHandle:
def __init__(self,filename,mode='r',encoding='utf-8'):
# self.filename=filename
self.file=open(filename,mode,encoding=encoding)
self.mode=mode
self.encoding=encoding
def write(self,line):
print('------------>',line)
t=time.strftime('%Y-%m-%d %X')
self.file.write('%s %s' %(t,line))
def __getattr__(self, item):
# print(item,type(item))
# self.file.read
return getattr(self.file,item)
f1=FileHandle('a.txt','w+')
# print(f1.file)
# print(f1.__dict__)
# print('==>',f1.read) #觸發__getattr__
# print(f1.write)
f1.write('1111111111111111\n')
f1.write('cpu負載過高\n')
f1.write('記憶體剩餘不足\n')
f1.write('硬碟剩餘不足\n')
# f1.seek(0)
# print('--->',f1.read())