標籤:time 就會 使用字串 建立對象 定義 creat 刪除對象 需要 目標
物件導向 3 進階用法Binder 方法:
Binder 方法,非Binder 方法
Binder 方法: 對象綁定,類綁定 @ classmethod
非綁定 @ staticmethod
class Foo: # 沒有裝飾器的函數,參數自動傳入對象,和對象綁定,是對象Binder 方法 def func1(self): print(self) # 使用classmethod裝飾,自動傳入類,和類綁定,是類的Binder 方法。 @ classmethod def func2(cls): print(cls) # 使用staticmethod裝飾,不自動傳入任何東西,就是普通方法 @ staticmethod def func3(): print(‘普通工具類‘)f = Foo()f.func1() # <__main__.Foo object at 0x000001DFFED06278>f.func2() # <class ‘__main__.Foo‘>f.func3() # 普通工具類
綁定對象方法,綁定類方法,非Binder 方法的使用
import dbimport time,hashlibclass People: def __init__(self,name,age): self.name = name self.age = age def info(self): print(‘my name is %s age is %s‘%(self.name,self.age)) # 函數依賴類的傳入 @classmethod def creat_obj(cls): obj = cls(db.name,db.age) return obj # 獨立的工具 @staticmethod def creat_id(): hs = hashlib.md5(str(time.time()).encode(‘utf8‘)) return hs.hexdigest()p1 = People(‘ql‘,22)p1.info()p2 = People.creat_obj() # 使用類方法直接建立對象p2.info()id = p2.creat_id()print(id)
property
class People: def __init__(self,name): self.__name = name # 將方法偽裝為屬性,調用時不需要加括弧。 @ property # name = property(name) def name(self): return self.__name # property 偽裝成屬性後,如果被賦值,將觸發 @ name.setter # name = name.setter(name) ==>name.name.__setter__() def name(self,name): self.__name = name return self.__name # property 偽裝成屬性後,如果被刪除,將觸發 @ name.deleter # 刪除name 觸發 def name(self): print(‘不準刪name‘)p = People(‘qianlei‘)p.name = ‘qianlei123‘print(p.name)將name 封裝,看似直接調用name,其實該name 是方法,可以對查看名稱進行定製。
反射
反射就是使用字串來作為屬性名稱,去調用。
class People: def __init__(self,name,age): self.name = name self.age = age def info(self): print(‘my name is %s age is %s‘%(self.name,self.age))p = People(‘qianlei‘,22)調用屬性時,如果接收使用者輸入,將字串作為屬性名稱,則無法調用。想調用可以使用字典 p.__dict__[‘name‘]python 還提供了簡單的解決辦法print(p.name)
反射 hasattr() getattr() setattr() delattr()
print(hasattr(p,‘name‘))print(getattr(p,‘name‘,None)) # 第三個參數為預設返回,如果沒有該屬性預設傳回值。print(getattr(p,‘name1‘,None))setattr(p,‘sex‘,‘male‘)print(getattr(p,‘sex‘))delattr(p,‘sex‘)print(getattr(p,‘sex‘,‘沒有這個屬性‘))
反射應用
class service(): def run(self): while True: res = input(‘>>>>‘).strip() # if hasattr(self,res): # 先判斷是否有這個屬性 # func = getattr(self,res) # 擷取屬性 # func() # 運行屬性 mes_list = res.split() if hasattr(self,mes_list[0]): func = getattr(self,mes_list[0]) func(mes_list[1]) def get(self,mes): print(‘get.......‘,mes) def put(self,mes): print(‘put.........‘,mes)s = service()s.run()
__call__ __new__ __str____call__ : 將類的執行個體變成可以調用的對象,執行個體+(),運行
class Foo: def __call__(self, *args, **kwargs): print(‘this is call func‘) print(args) print(kwargs)f = Foo()f(‘a‘, b=1)===》this is call func===》(‘a‘,)===》{‘b‘: 1}
__new__ : 類執行個體化時自動調用,可以定製執行個體化。
class Foo: def __new__(cls, *args, **kwargs): print(‘this is new func‘) print(args) print(kwargs)f = Foo(‘a‘, b=1)===》this is new func===》(‘a‘,)===》{‘b‘: 1}
__str__ :列印執行個體時調用。
class Foo: def __str__(self): return ‘this is str‘f = Foo()print(f)===》this is str
_
getattr_ __setattr__ __delattr__
定製對象擷取設定刪除屬性方法:_getattr_() _setattr_() _delattr_()
_getattribut_():對象調用屬性時啟用,但是當拋出AttributError() 則啟用_getattr_(),需要自己設定。
_getattr_() :對象調用屬性時沒有對應屬性,則啟用_getattr_()
_setattr_() :對象設定屬性時啟用運行,並且返回該方法的傳回值。可以規定修改屬性時返回什麼。
_delattr_():對象刪除屬性時啟用運行,並且返回該方法的傳回值。可以規定刪除屬性時返回什麼。
class Test(): def __init__(self,name): self.name=name def __getattr__(self, item): print(‘getattr is running %s was not find ‘%item) def __setattr__(self, key, value): print(‘setattr is running %s is seting‘%key) # self.key=value#這個方法會調用自己,因為方法本身就是添加屬性,無限遞迴 self.__dict__[key]=value#設定時需要使用對象字典 def __delattr__(self, item): print(‘delattr is running %s is del‘%item) del self.__dict__[item]#刪除對象字典元素,否則會無限遞迴。t=Test(‘tes‘) #只要有屬性產生或變動就會觸發__setattr__print(t.erro_name)#調用不存在的屬性 就會觸發 __getattr__()方法t.age=20 #只要有屬性產生就會觸發__setattr__print(t.__dict__)del t.age#只要刪除屬性就會觸發__delattr__print(t.__dict__)
二次加工標準模型
使用繼承,定製自己的類。
就是使用繼承對標準模型,進行個人化定製,
添加自己的需求,並且還可以使用標準模型的功能。
例如對列表進行定製,執行個體化列表時,要求必須傳入字串。
class Mylist(list): def __init__(self, strtype): if isinstance(strtype, str): super().append(strtype) else: print(‘必須傳入字串‘)# 這裡必須傳入字串l = Mylist(‘123‘)print(l)# 還可以使用原來的功能。l.append(‘abc‘)print(l)
授權:
利用目標類的執行個體,去調用目標類的方法。相當於利用目標類的執行個體授權目標類的方法。
1、先給類中添加目標類的執行個體
2、需要調用目標類中的方法時,使用__getattr__()去轉接目標類的方法。
3、需要修改目標類的方法時,則利用目標類的執行個體給出對應的方法,並封裝修改。
import timeclass file_io(): def __init__(self,filename,mode,encoding=‘utf-8‘): self.file=open(filename,mode,encoding=encoding)#給執行個體屬性添加個open()執行個體,利用這個執行個體給自己添加open()中的方法。 self.mode=mode self.encoding=encoding # 自己定義write()方法,本質上還是調用檔案對象的write()方法,給予了定製功能 def write(self,neirong): #利用open()執行個體file,授權write方法,定製封裝自己的write()方法。 #每次寫入內容時添加時間。 t = time.strftime(‘%Y-%m-%d %X‘) res=‘%s %s‘%(t,neirong) return self.file.write(res)#返迴文件控制代碼中的write() # 調用本類沒有的方法時,去對象的類中去找。。 def __getattr__(self, item): #利用__getattr__()方法去授權對象調用open()的執行個體file,中的各種方法。 return getattr(self.file,item)#授權f對象使用標準檔案控制代碼中的各種屬性。f=file_io(‘test.txt‘,‘w+‘)f.file.write(‘None\n‘)#f對象調用自己的屬性file,file控制代碼中有write()方法f.write(‘qwe\n‘) #調用定製的write()方法 f.write(‘sdad\n‘)f.seek(0)print(f.read())#f中沒有read()方法,所以觸發__getattr__(),返迴文件控制代碼本身提供的read()f.close()
python 課堂15 物件導向3 內部方法,類的定製