python 反射和动态加载_Python的反射
什么是反射
反射是一個很重要的概念,它可以把字符串映射到實例的變量或者實例的方法然后可以去執(zhí)行調(diào)用、修改等操作。它有四個重要的方法:
getattr 獲取指定字符串名稱的對象屬性
setattr 為對象設置一個對象
hasattr?判斷對象是否有對應的對象(字符串)
delattr 刪除指定屬性
attr是屬性英文的前幾個字母,屬性指的是類中類變量、實例變量和方法。但是要注意不能是私有的,如果你的變量是以“_”開頭,那將無法獲取。
反射常常用在動態(tài)加載模塊的場景中。
#!/usr/bin/env python#-*- coding: utf-8 -*-#Author: rex.cheny#E-mail: rex.cheny@outlook.com
classTestObj(object):def __init__(self, name, age):
self.name=name
self.age=agedefdisplayName(self):print("displayName方法執(zhí)行,打印姓名:", self.name)defAAA(self):print("I am AAA.")defmain():
to= TestObj("Tom", 23)#查看 to 實例里面是否有 name 這個屬性
if hasattr(to, "name"):print("實例 to 中有 name 屬性。")print(getattr(to, "name"))else:print("實例 to 中沒有 name 屬性。")if hasattr(to, "displayName"):print("實例 to 中有 displayName 屬性。")
getattr(to,"displayName")()else:print("實例 to 中沒有 displayName 屬性。")if hasattr(to, "AAA"):print("實例 to 中有 AAA 屬性。")
getattr(to,"AAA")()else:print("實例 to 中沒有 AAA 屬性,將會設置。")
setattr(to,"AAA", AAA) #參數(shù):實例、方法名稱、具體方法 相當于 to.AAA = AAA 第一個AAA是函數(shù)在實例中的名稱, 第二個AAA是把哪個函數(shù)放進去,兩者只是恰好這里名稱一樣
#to.AAA(to) # 這里一定要主動傳遞一個實例進去,因為它不會自動裝配self
getattr(to, "AAA")(to)if __name__ == '__main__':
main()
AAA是動態(tài)裝載到實例里面去的。
可能有些人還沒明白反射,反射就是把字符串反射成內(nèi)存對象,看下面的例子
#!/usr/bin/env python#-*- coding: utf-8 -*-#Author: rex.cheny#E-mail: rex.cheny@outlook.com
classTestObj(object):def __init__(self, name):
self.name=namedefdisplayname(self):print(self.name)defmain():
to= TestObj(name="Tom")
cmd= input("輸入:")ifhasattr(to, cmd):pass
else:
setattr(to, cmd, displayname)
func=getattr(to, cmd)
func(to)if __name__ == '__main__':
main()
根據(jù)用戶輸入來調(diào)用函數(shù)(這個函數(shù)肯定要提前的真實存在)。我這里無論我輸入什么都可以執(zhí)行上面的displayname方法。現(xiàn)在應該明白字符串映射到方法了吧。
反射使用
通過字符串導入模塊
#!/usr/bin/env python#-*- coding: utf-8 -*-#Author: rex.cheny#E-mail: rex.cheny@outlook.com
temp= "re"model= __import__(temp)defmain():
txt= "hj123uo"pattern= model.compile(r"[0-9]+")print(model.search(pattern, txt).group())if __name__ == '__main__':
main()
以字符串的形式使用模塊的方法
#!/usr/bin/env python#-*- coding: utf-8 -*-#Author: rex.cheny#E-mail: rex.cheny@outlook.com
temp= "re" #要引入的模塊
func = "compile" #要使用的方法
model = __import__(temp) #導入模塊
function = getattr(model, func) #找到模塊中的屬性
defmain():
txt= "hj123uo"pattern= function(r"[0-9]+") #這里執(zhí)行funcation()就等于執(zhí)行re.compile()函數(shù)
print(model.search(pattern, txt).group())if __name__ == '__main__':
main()
反射到底有什么用?
上面使用re.compile()函數(shù)的整個過程看起來很麻煩,但是你要知道這就等于實現(xiàn)了動態(tài)加載和執(zhí)行所需要的模塊或方法而不需要全部寫入到PY文件中,當然具體需要執(zhí)行的方法你也要提前實現(xiàn)。典型的使用場景就是web的URL路由。目前所有的web框架的URL路由基本都是這個原理。
用戶輸入不同的URL如何加載不同的PY文件以及調(diào)用里面的方法呢?你想一想Django里面,它并不是這樣的,它依然需要你設置URL以及該URL對應的PY文件,為什么?因為這樣調(diào)試方便,當然你能力足夠也可以給它改寫成反射的機制。
總結(jié)
以上是生活随笔為你收集整理的python 反射和动态加载_Python的反射的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统中的死锁问题
- 下一篇: python中提供怎样的内置库、可以用来