1. 程式人生 > 程式設計 >小結Python的反射機制

小結Python的反射機制

前言:

前兩天用Python實現了ftp伺服器。在小專案中就用到了反射。因此寫個筆記鞏固下。

反射的定義:檢測和修改它本身狀態或行為的一種能力(自省)。

而通過反射,Python可以通過字串的對映或修改程式執行的狀態和方法。

反射的四個方法。hasattr,getattr,setattr,delattr

hasattr:判斷一個方法是否存在與這個類中

class Person(object):
  def __init__(self,name):
    self.name = name
  def talk(self):
    print("%s正在交談"%self.name)

p = Person("laowang")    
print(hasattr(p,"talk"))  # True。因為存在talk方法
print(hasattr(p,"name"))  # True。因為存在name變數
print(hasattr(p,"abc"))   # False。因為不存在abc方法或變數

getattr:根據字串去獲取obj物件裡的對應的方法的記憶體地址,加"()"括號即可執行

class Person(object):
  def __init__(self,name):
    self.name = name
  def talk(self):
    print("%s正在交談"%self.name)
p = Person("laowang")

n = getattr(p,"name")  # 獲取name變數的記憶體地址
print(n)        # 此時列印的是:laowang

f = getattr(p,"talk")  # 獲取talk方法的記憶體地址
f()           # 呼叫talk方法

我們發現getattr有三個引數,那麼第三個引數是做什麼用的呢?
s = getattr(p,"abc","not find")
print(s)        # 列印結果:not find。因為abc在物件p中找不到,本應該報錯,但因為修改了找不到就輸出not find

setattr:通過setattr將外部的一個函式繫結到例項中

def abc(self):
  print("%s正在交談"%self.name)

class Person(object):
  def __init__(self,name):
    self.name = name

p = Person("laowang")
setattr(p,"talk",abc)  # 將abc函式新增到物件中p中,並命名為talk
p.talk(p)        # 呼叫talk方法,因為這是額外新增的方法,需手動傳入物件


setattr(p,"age",30)   # 新增一個變數age,複製為30
print(p.age)      # 列印結果:30

delattr:刪除一個例項或者類中的方法

class Person(object):
  def __init__(self,name):
    self.name = name
  def talk(self):
    print("%s正在交談"%self.name)

p = Person("laowang")

delattr(p,"name")    # 刪除name變數
print(p.name)      # 此時將報錯

為什麼用反射

好處一:

實現可插拔機制

可以事先定義好介面,介面只有在被完成後才會真正執行,這實現了即插即用,這其實是一種‘後期繫結'

好處二:

動態匯入模組(基於反射當前模組成員)

以上就是小結Python的反射機制的詳細內容,更多關於python 反射的資料請關注我們其它相關文章!