Python反射

2018-06-08 17:19 更新

反射的定義

根據(jù)字符串的形式去某個對象中操作成員

  1. 根據(jù)字符串的形式去一個對象中尋找成員

  2. 根據(jù)字符串的形式去一個對象中設(shè)置成員

  3. 根據(jù)字符串的形式去一個對象中刪除成員

  4. 根據(jù)字符串的形式去一個對象中判斷成員是否存在


初始反射

通過字符串的形式,導(dǎo)入模塊

根據(jù)用戶輸入的模塊名稱,導(dǎo)入對應(yīng)的模塊并執(zhí)行模塊中的方法

  1. # Python使用的是3.5.1

  2. [root@root ~]# python -V

  3. Python 3.5.1

  4. # commons.py為模塊文件

  5. [root@root ~]# ls

  6. commons.py  reflection.py

  7. # commons.py文件內(nèi)容

  8. [root@root ~]# cat commons.py

  9. #!/usr/bin/env python

  10. # 定義了連個函數(shù),f1和f2

  11. def f1():

  12.    return "F1"

  13. def f2():

  14.    return "F2"

  15. [root@root ~]# cat reflection.py

  16. #!/usr/bin/env python

  17. # _*_ coding:utf-8 _*_

  18. # 輸入模塊的名稱

  19. mod_name = input("請輸入模塊名稱>>> ")

  20. # 查看輸入的內(nèi)容及數(shù)據(jù)類型

  21. print(mod_name, type(mod_name))

  22. # 通過__import__的方式導(dǎo)入模塊,并賦值給dd

  23. dd = __import__(mod_name)

  24. # 執(zhí)行f1()函數(shù)

  25. ret = dd.f1()

  26. # 輸出函數(shù)的返回值

  27. print(ret)

  28. # 執(zhí)行reflection.py

  29. [root@ansheng ~]# python reflection.py

  30. # 輸入模塊名稱

  31. 請輸入模塊名稱>>> commons

  32. # 返回輸入的內(nèi)容及數(shù)據(jù)類型

  33. commons <class 'str'>

  34. # 執(zhí)行F1函數(shù)

  35. F1

通過字符串的形式,去模塊中尋找指定函數(shù),并執(zhí)行

用戶輸入模塊名稱和函數(shù)名稱,執(zhí)行指定模塊內(nèi)的函數(shù)or方法

  1. [root@root ~]# cat commons.py

  2. #!/usr/bin/env python

  3. def f1():

  4.    return "F1"

  5. def f2():

  6.    return "F2"

  7. [root@root ~]# cat reflection.py

  8. #!/usr/bin/env python

  9. # _*_ coding:utf-8 _*_

  10. # 輸入模塊的名稱

  11. mod_name = input("請輸入模塊名稱>>>")

  12. # 輸入函數(shù)or方法的名稱

  13. func_name = input("請輸入函數(shù)名稱>>>")

  14. # 導(dǎo)入模塊

  15. dd = __import__(mod_name)

  16. # 導(dǎo)入模塊中的方法

  17. target_func = getattr(dd, func_name)

  18. # 查看target_func和dd.f1的內(nèi)存地址

  19. print(id(target_func), id(dd.f1))

  20. # 執(zhí)行target_func()函數(shù)

  21. result = target_func()

  22. # 輸出結(jié)果

  23. print(result)

  24. [root@root ~]# python reflection.py

  25. # 輸入模塊名稱commons

  26. 請輸入模塊名稱>>>commons

  27. # 輸入函數(shù)名稱f1

  28. 請輸入函數(shù)名稱>>>f1

  29. # 返回內(nèi)存地址

  30. 139844714989224 139844714989224

  31. # 執(zhí)行的函數(shù)返回結(jié)果

  32. F1

反射相關(guān)的函數(shù)

getattr(object, name[, default])

根據(jù)字符串的形式去一個對象中尋找成員

  1. # 自定義模塊的內(nèi)容

  2. [root@root ~]# cat commons.py

  3. #!/usr/bin/env python

  4. Blog_Url = "https://yw666.blog.51cto.com"

  5. def f1():

  6.    return "F1"

  7. def f2():

  8.    return "F2"


  1. >>> import commons

  2. >>> getattr(commons, "f1")

  3. <function f1 at 0x7fbce5774598>

  4. >>> getattr(commons, "f1f1f1")

  5. Traceback (most recent call last):

  6.  File "<stdin>", line 1, in <module>

  7. AttributeError: module 'commons' has no attribute 'f1f1f1'

執(zhí)行獲取到的函數(shù)

  1. >>> target_func = getattr(commons, "f1")

  2. >>> target_func

  3. <function f1 at 0x7fbce5774598>

  4. >>> target_func()

  5. 'F1'

通過設(shè)置默認值可以避免獲取不到方法時報錯

  1. # 設(shè)置一個默認值為None

  2. >>> target_func = getattr(commons, "f1f1f1", None)

  3. >>> target_func

  4. >>>

通過getattr獲取模塊中的全局變量

  1. >>> import commons

  2. >>> getattr(commons, "Blog_Url", None)

  3. 'https://yw666.blog.51cto.com'

  • setattr(object, name, value)

根據(jù)字符串的形式去一個對象中設(shè)置成員

設(shè)置全局變量

  1. # 獲取commons內(nèi)的Name變量

  2. >>> getattr(commons, "Name", None)

  3. # 在commons模塊中設(shè)置一個全局變量Name,值為Ansheng

  4. >>> setattr(commons, "Name", "YangWen")

  5. # 獲取commons內(nèi)的Name變量

  6. >>> getattr(commons, "Name", None)

  7. 'YangWen'

getattr結(jié)合lambda表達式設(shè)置一個函數(shù)

  1. >>> setattr(commons, "as", lambda : print("as"))

  2. >>> getattr(commons, "as")

  3. <function <lambda> at 0x000001FD3E51FD90>

  4. >>> aa = getattr(commons, "as")

  5. >>> aa()

  6. as

  • delattr(object, name)

根據(jù)字符串的形式去一個對象中刪除成員

  1. >>> getattr(commons, "Name")

  2. 'Ansheng'

  3. >>> delattr(commons, "Name")

  4. # 獲取不到就報錯

  5. >>> getattr(commons, "Name")

  6. Traceback (most recent call last):

  7.  File "<stdin>", line 1, in <module>

  8. AttributeError: module 'commons' has no attribute 'Name'

hasattr(object, name)

根據(jù)字符串的形式去一個對象中判斷成員是否存在

  1. # 如果不存在就返回False

  2. >>> hasattr(commons, "Name")

  3. False

  4. >>> setattr(commons, "Name", "YangWen")

  5. # 如果存在就返回True

  6. >>> hasattr(commons, "Name")

  7. True

(雙下劃線)import(雙下劃線)方式導(dǎo)入多層模塊

  1. >>> m = __import__("lib.commons")    

  2. >>> m

  3. # 返回的路徑是`lib`

  4. <module 'lib' (namespace)>

  5. >>> m = __import__("lib.commons", fromlist=True)

  6. >>> m

  7. # 返回的路徑是`lib.commons`

  8. <module 'lib.commons' from '/root/lib/commons.py'>

基于反射模擬Web框架路由系統(tǒng)

find_index.py文件內(nèi)容

  1. #!/usr/bin/env python

  2. # _*_ coding:utf-8 _*_

  3. url = input("請輸入url: ")

  4. target_module, target_func = url.split('/')

  5. m = __import__("lib." + target_module, fromlist=True)

  6. if hasattr(m, target_func):

  7.    target_func = getattr(m, target_func)

  8.    r = target_func()

  9.    print(r)

  10. else:

  11.    print("404")

目錄結(jié)構(gòu)及文件內(nèi)容

  1. [root@ansheng ~]# tree ./

  2. ./

  3. ├── find_index.py

  4. └── lib

  5.    ├── account.py

  6.    └── commons.py

  7. 1 directory, 3 files

  8. [root@root ~]# cat lib/commons.py

  9. #!/usr/bin/env python

  10. Blog_Url = "yw666.blog.51cto.com"

  11. def f1():

  12.    return "F1"

  13. def f2():

  14.    return "F2"

  15. [root@root ~]# cat lib/account.py

  16. #!/usr/bin/env python

  17. # _*_ coding:utf-8 _*_

  18. def login():

  19.    return "login"

  20. def logout():

  21.    return "logout"

執(zhí)行

  1. [root@root ~]# python find_index.py

  2. 請輸入url: account/login

  3. login

  4. [root@root ~]# python find_index.py

  5. 請輸入url: account/logout

  6. logout

  7. [root@root ~]# python find_index.py

  8. 請輸入url: commons/f1

  9. F1

  10. [root@root ~]# python find_index.py

  11. 請輸入url: commons/f2

  12. F2

  13. [root@root ~]# python find_index.py

  14. 請輸入url: commons/asdasd

  15. 404


本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號