Python學習-反射相關函數

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 。





源自運維之路

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章