第三十四篇 Python物件導向之 反射(自省)

來源:互聯網
上載者:User

標籤:use   設計   狀態   medium   租房   代碼   format   機制   邏輯   

什麼是反射?

反射的概念是由Smith在1982年提出的,主要是指程式可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了電腦科學領域關於應用反射性的研究。它首先被程式語言的設計領域所採用,並在Lisp和物件導向方面取得了成就。

四個可以實現自省的函數,是Python的內建函數
    下列方法適用於類和對象
    • 先看這四個方法對執行個體(b1)的使用
# 示範代碼class BlackMedium:    feature = ‘Ugly‘    def __init__(self, name, address):        self.name = name        self.address = address    def sell_house(self):        print("[%s] 是賣房子的,sb才從它這買" %self.name)    def rent_house(self):        print("[%s] 是租房子的,sb才從它這租,它黑人" %self.name)# 執行個體化b1 = BlackMedium(‘某某置業‘, ‘回龍觀‘)
  • hasattr(object, name):判斷object裡有沒有一個name字串(‘屬性名稱‘)對應的方法或屬性。

  object:表示對象; name:屬性名稱,是字串形式;

# 檢測資料屬性print(hasattr(b1, ‘name‘))        # True     # b1.__dict__[‘name‘]# 檢測函數屬性print(hasattr(b1, ‘sell_house‘))  # Trueprint(hasattr(b1, ‘sell_housereqre‘))  # False
  • getattr(object, name, default=None): 擷取屬性值

  object:表示對象; name:屬性名稱,是字串形式;value:屬性對應的值

# 擷取屬性的具體值print(getattr(b1, ‘name‘))   # 某某置業print(getattr(b1, ‘rent_house‘))  # <bound method BlackMedium.rent_house of <__main__.BlackMedium object at 0x00B52F50>>func = getattr(b1, ‘rent_house‘)func()    # [某某置業] 是租房子的,sb才從它這租,它黑人print(getattr(b1, ‘feature‘))   # Ugly# default 參數print(getattr(b1, ‘sell_house323‘, ‘沒有這個屬性‘)) # 沒有這個屬性getattr()  # 等價於 b1.sell_house
  • setattr(object, name, value): 修改或者新增屬性及值

  object:表示對象; name:屬性名稱,是字串形式;value:屬性對應的值

# setattr設定資料屬性setattr(b1, ‘sb‘, True)setattr(b1, ‘sb1‘, 1234)setattr(b1, ‘name‘, "萬神置業")setattr(b1, ‘feature‘, ‘黑中介‘)print(b1.__dict__)#  {‘name‘: ‘萬神置業‘, ‘address‘: ‘回龍觀‘, ‘sb‘: True, ‘sb1‘: 1234, ‘feature‘: ‘黑中介‘}# setattr設定函數屬性setattr(b1, ‘funct‘, lambda x:x+1)setattr(b1, ‘funct1‘, lambda self:self.name+"ss")print(b1.__dict__)# {‘name‘: ‘萬神置業‘, ‘address‘: ‘回龍觀‘, ‘sb1‘: 1234, ‘feature‘: ‘黑中介‘, ‘funct‘: <function <lambda> at 0x02FEB618>}# 調用新增的函數屬性print(b1.funct(10))     # 11print(b1.funct1(b1))    # 萬神置業ss
  • delattr(object, name)  刪除屬性。

  object:表示對象; name:屬性名稱,是字串形式

delattr(b1, ‘sb‘)   # 等於 del b1.sbprint(b1.__dict__)#  {‘name‘: ‘萬神置業‘, ‘address‘: ‘回龍觀‘, ‘sb1‘: 1234, ‘feature‘: ‘黑中介‘}
    •   再看這四個方法對類(BlackMedium)的使用 
# 定義類,但沒有進行執行個體化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)
# hasattr()print(hasattr(BlackMedium,‘feture‘))  # Trueprint(getattr(BlackMedium,‘feture‘))print(setattr(BlackMedium, ‘feture‘, ‘黑中介‘))print(getattr(BlackMedium, ‘feture‘))  # 黑中介delattr(BlackMedium, ‘sell_hourse‘)print(BlackMedium.__dict__)# {‘__module__‘: ‘__main__‘, ‘feture‘: ‘黑中介‘, ‘__init__‘: <function BlackMedium.__init__ at 0x007D1B70>, ‘rent_hourse‘: <function BlackMedium.rent_hourse at 0x007D1AE0>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘BlackMedium‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘BlackMedium‘ objects>, ‘__doc__‘: None}#

二. 為什麼用反射?

是項目中,一個項目有多個程式員寫,如果A寫程式的時候要用到B所寫的類,但是B休假了,還沒有完成他寫的類,A想到了反射,使用了反射機制A可以繼續完成自己的代碼,等B休假回來後再繼續完成類的定義並且實現A想要的功能。

總之,反射好處就是,可以事先定義好介面,介面只有在被完成後才會真正執行,這實現了隨插即用,這其實是一種“後期綁定”,什麼意思?即你可以事先把主要的邏輯寫好(只定義介面),然後後期再去實現介面的功能。

示範:

class FtpClient:    ‘ftp用戶端,還沒具體實現功能‘    def __init__(self,addr):        print("正在串連伺服器[{}]".format(addr))        self.addr = addrf1 = FtpClient(‘192.168.123.123‘)# f1.put()   # 因為B還沒定義put()方法,所以會報錯,不能這麼幹,所以需要用下面的判斷做if hasattr(f1,‘put‘):   # 判斷f1裡是否有put 方法    func_get =  getattr(f1, ‘put‘)   # 如果有,就可以get到這個方法    func_get()   # 然後運行這個方法else:    print("執行其他邏輯")     # 如果沒有put這個方法,就執行其他邏輯#  結果正在串連伺服器[192.168.123.123]執行其他邏輯
B只定義了介面,還沒實現功能
class FtpClient:    ‘ftp用戶端,還沒具體實現功能‘    def __init__(self,addr):        print("正在串連伺服器[{}]".format(addr))        self.addr = addr    # B休假回來了,實現了put方法    def put(self):        print("檔案開始上傳了")# from try import FtpClientf1 = FtpClient(‘192.168.123.123‘)# f1.put()if hasattr(f1,‘put‘):   # 判斷f1裡是否有put 方法    func_get =  getattr(f1, ‘put‘)   # 如果有,就可以get到這個方法    func_get()   # 然後運行這個方法else:    print("執行其他邏輯")     # 如果沒有put這個方法,就執行其他邏輯#結果正在串連伺服器[192.168.123.123]檔案開始上傳了
B休假回來,實現了A想要的方法

 

第三十四篇 Python物件導向之 反射(自省)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.