日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面向对象高级(上)

發(fā)布時(shí)間:2025/7/14 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面向对象高级(上) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1 判斷類型和子類

  判斷對(duì)象是否是屬于某個(gè)類的

isinstance(對(duì)象名, 類名)

    注意: 如果是它的父類, 同樣也返回True; 但是 (父類的對(duì)象, 子類) 返回的是Fale

  查看父類, 注意是使用類名而不是對(duì)象

類名.__bases__

  判斷是否是某個(gè)類的子類

issubclass(子類名, 父類名)

2 反射

  反射是指程序可以訪問、檢測(cè)和修改它本身狀態(tài)或行為的一種能力  

2.1 反射參數(shù)

  可以通過不同的字符串來反射不同的參數(shù), 進(jìn)而進(jìn)行一定的操作; 或者反射一些函數(shù)來執(zhí)行

  在Python中主要是使用內(nèi)置函數(shù)hasattr,?getattr, setattr, delattr三個(gè)函數(shù)

  hassattr(), 判斷對(duì)象或者類是否具有摸個(gè)參數(shù), 第一個(gè)參數(shù)是類或者對(duì)象, 第二個(gè)參數(shù)是字符串類型的名字, 返回值是True或者False

class People:def run(self):print('running..')print( hasattr(People() , 'run') ) print( hasattr(People , 'run') )

  getattr(), 獲取對(duì)象或者類的參數(shù),?第一個(gè)參數(shù)是類或者對(duì)象, 第二個(gè)參數(shù)是字符串類型的名字,但是使用對(duì)象和類室友區(qū)別的

  另外還可以設(shè)置第三個(gè)參數(shù), 當(dāng)該屬性不存在的時(shí)候返回那個(gè)值

whc = People() func = getattr(whc, 'run') func() func = getattr(People, 'run') func(whc) print( getattr(whc, 'running', '該屬性不存在') )

  setattr(), 設(shè)置屬性, 同樣可以給對(duì)象和類綁定

whc = People() setattr(whc, 'name', 'weihuchao') setattr(People, 'country', 'China') print(whc.__dict__) print(People.__dict__)

  delattr(), 刪除屬性

delattr(whc, 'name') delattr(People,'country') print(whc.__dict__) print(People.__dict__)

  使用反射的好處,?可插拔機(jī)制

    因?yàn)榭梢圆榭搭愔惺欠窈心硨傩? 在不同模塊寫程序的時(shí)候, 只需要判斷該屬性有沒有就可使程序健壯的完成, 而不必要等待相關(guān)聯(lián)的模塊完成

2.2 反射模塊

  在正常使用的導(dǎo)入模塊是使用import或者from, 但是要反射某個(gè)模塊, 同樣是根據(jù)輸入的字符串的來反射  

  具體的反射有兩種操作, 一個(gè)是內(nèi)置函數(shù)__import__(), 另一個(gè)是使用模塊importlib

  具體模式如下

返回值 = __import__(模塊名字字符串) #或者 import importlib 返回值 = importlib.import_module(模塊名字字符串)

  返回值就是相當(dāng)于反射回來的命名空間的名字

  一般建議使用第二種方法

name = 'time' nameSpace = __import__(name) print(nameSpace.time()) #或者 import importlib name = 'time' nameSpace = importlib.import_module(name) print(nameSpace.time())

  另外反射的例子

3 __getattr__等

  在類中, 還可以定義__getattr__(),?__setattr__() 和?__deltattr__()

  定義了__setattr__() 和?__deltattr__()函數(shù)之后, 類中所有的設(shè)置, 刪除屬性和方法的時(shí)候都會(huì)調(diào)用它

    具體來說, 由于設(shè)置了這兩個(gè)函數(shù), 所以在完成設(shè)置和刪除功能的時(shí)候, 不能再使用賦值語句和setattr()這個(gè)內(nèi)置函數(shù)的處理了

    要處理結(jié)果需要使用__dict__屬性來完成

    __setattr__() 默認(rèn)有三個(gè)參數(shù), 一個(gè)是self, 第二個(gè)是鍵, 第三個(gè)是值

    __deltattr__()認(rèn)有兩個(gè)個(gè)參數(shù),一個(gè)self, 另一個(gè)是需要?jiǎng)h除的屬性的名字

  但是__getattr__()函數(shù)特殊, 它是在調(diào)用attr不存在的時(shí)候才調(diào)用, 基于這個(gè)特性有很強(qiáng)的使用效果

  具體的實(shí)例如下

class Foo:x=1def __init__(self,y):self.y=ydef __getattr__(self, item):print('----> from getattr:你找的屬性不存在')def __setattr__(self, key, value):print('----> from setattr')# self.key=value #這就無限遞歸了,# self.__dict__[key]=value #應(yīng)該使用它def __delattr__(self, item):print('----> from delattr')# del self.item #無限遞歸了self.__dict__.pop(item)#__setattr__添加/修改屬性會(huì)觸發(fā)它的執(zhí)行 f1=Foo(10) print(f1.__dict__) # 因?yàn)槟阒貙懥薩_setattr__,凡是賦值操作都會(huì)觸發(fā)它的運(yùn)行,你啥都沒寫,就是根本沒賦值,除非你直接操作屬性字典,否則永遠(yuǎn)無法賦值 f1.z=3 print(f1.__dict__)#__delattr__刪除屬性的時(shí)候會(huì)觸發(fā) f1.__dict__['a']=3#我們可以直接修改屬性字典,來完成添加/修改屬性的操作 del f1.a print(f1.__dict__)#__getattr__只有在使用點(diǎn)調(diào)用屬性且屬性不存在的時(shí)候才會(huì)觸發(fā) f1.xxxxxx

4 授權(quán)

  授權(quán)是__getattr__()函數(shù)的應(yīng)用

  具體實(shí)例是實(shí)現(xiàn)一個(gè)記錄日志的Open類

  在__init__()函數(shù)中, 可以通過傳入的內(nèi)容來獲得文件句柄, 再編寫一個(gè)write()函數(shù), 通過文件句柄寫入日志信息即可

  但是除了wirte()函數(shù)功能之外別的文件函數(shù)像close()和flush()等都不需要修改的, 但是總不能每一個(gè)都寫一遍

  所以利用__getattr__()不存在屬性調(diào)用的特性, 利用__getattr__()有兩個(gè)參數(shù)一個(gè)是self另一個(gè)就是獲取的屬性名這個(gè)特性, 通過內(nèi)置函數(shù)getattr()來具體取得那些相關(guān)屬性 

  具體代碼如下

import time class LogFile:def __init__(self,filename,mode='r',encoding='utf-8'):self.file=open(filename,mode,encoding=encoding)def write(self,line):t=time.strftime('%Y-%m-%d %T')self.file.write('%s %s' %(t,line))def __getattr__(self, item):print("aaa")return getattr(self.file,item)f1=LogFile('log', 'w+') f1.write('create logs..') f1.seek(0) print(f1.read()) f1.close()

5 包裝

  通過繼承基本類型list, 來獲得list的全部功能, 通過重寫append()方法, 來加入對(duì)添加進(jìn)來的值進(jìn)行類型判斷, 從而實(shí)現(xiàn)自定義功能

  具體代碼如下

class List(list):def append(self, p_object):if not isinstance(p_object,int):raise TypeError('插入的值必須是int類型的!')super().append(p_object)myList = List([1,2,3,4]) print(myList) myList.append(5) print(myList) try:myList.append('test') except:print("輸入值類型不正確") print(myList)

  

轉(zhuǎn)載于:https://www.cnblogs.com/weihuchao/p/6757345.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的面向对象高级(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。