getattr()
先創建一個類,將所有函數放在類裏。在調用前先實例化該類,不論類裏有多少個函數,直接根據輸入內容通過getattr調用類裏的函數.
#!/usr/bin/env python # coding=utf-8 class getfun: def fun1(self): print 'processNavigate' def fun2(self): print 'processCreateTab' action = raw_input('請輸入地址:') newfun = getfun() fun = getattr(newfun,action) fun()
getattr的另一個常用示例就是在多個web頁面的情況下。在入口文件裏經常需要用到getattr函數智能處理不同的頁面請求。先看下一個常見的頁面結構:
# tree . ├── backend │ ├── account.py │ ├── account.pyc │ ├── admin.py │ ├── admin.pyc │ ├── __init__.py │ └── __init__.pyc ├── index.py -----> if版入口文件 └── web.py -----> getattr版入口文件
admin.py和account代碼比較簡單,單純爲了測試,這裏只是print內容
[root@www backend]# cat admin.py #!/usr/bin/env python # coding=utf-8 def index(): print 'welcome to your, administrator !' [root@www backend]# cat account.py #!/usr/bin/env python # coding=utf-8 def login(): print 'login now ******* ' def logout(): print 'logout now ******* '
先看下if版的用法:
[root@www web]# cat index.py #!/usr/bin/env python # coding=utf-8 from backend import account data = raw_input('請輸入地址:') if data == 'account/login': account.login() elif data == 'account/logout': account.logout()
這裏只import了account ,對登陸和登出做了判斷。如果需要登陸後臺,還要import admin,並對admin裏的方法再做判斷。同樣如果有還blog 、bbs 、usercenter等相關N個頁面時,這個判斷結構是不可想象的.
getattr的方法處理
[root@www web]# cat web.py #!/usr/bin/env python # coding=utf-8 data = raw_input('請輸入地址:') array = data.split('/') userspance = __import__('backend.'+array[0]) model = getattr(userspance , array[0]) func = getattr(model,array[1]) func()
這裏先通過輸入內容通過split進行了切分,如輸入的account/login ,會切分成數組[ account, login ] ,而輸入是admin/index則切分成[ admin, index ] 。由於引用的函數在當前目錄下的子目錄下,所以這裏需要通過backend連接引入。
這裏爲什麼是兩次getattr調用才能將結果輸出呢?這裏其實可以使用入門篇裏的dir方法查看,也可以通過使用inspect模塊進行判斷、獲取對象。通過dir分析結果如下:
>>> userspance = __import__('backend.'+ 'admin') >>> dir(userspance) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'admin'] >>> model = getattr(userspance,'admin') >>> dir(model) ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'index'] >>> getattr(model,'index') <function index at 0x7f572801a9b0> >>> getattr(model,'index')() welcome to your, administrator !
看看直接執行後的效果:
[root@www web]# python web.py 請輸入地址:admin/index welcome to your, administrator ! [root@www web]# python web.py 請輸入地址:account/login login now ******* [root@www web]# python web.py 請輸入地址:account/logout logout now *******
效果非常好,在backend裏論有多少個頁面,都可以通過這一段完成調用。完全不用做一大堆的import和if 判斷。這裏之所以和上面不一樣兩次getattr,是由於引用內容在子目錄下。
hasattr、setattr與delattr
先創建一個簡單的類:
#!/usr/bin/python # coding=utf-8 class test: def __init__(self): self.name = 'www.le.com' def setName(self,name): self.name = name def getName(self): return self.name def greet(self): print "Hello,I'm %s" %self.name foo = test()
1、hasattr(object,name)
hasattr判斷object中是否具有name屬性,返回的是一個布爾值。存在則返回True,不存在返回flase 。
foo = test() print hasattr(foo,'abc')
在類實例化後,通過上面的方法調用測試,因爲不存在abc,方法,所以這裏返回flase。將abc更換爲getName則返回True 。
2、setattr(object,name,default)
該函數會對現有的name字符串賦值或新增一個name並對其賦值。在對上面的test類實例化爲foo後,在其後加入如下代碼:
setattr(foo,'age',18) print getattr(foo,'age') print getattr(foo,'name') setattr(foo,'name','newname') print getattr(foo,'name')
執行後輸出內容如下:
18 www.361way.com newname
3、delattr(object,'name')
其主要用於刪除一個name字符串的值。後面新增代碼如下:
delattr(foo,'name') print getattr(foo,'name','not find')
這裏執行後的輸出爲not find 。
源自運維之路