1. 程式人生 > >詳細講述python自省函式getattr的用法

詳細講述python自省函式getattr的用法

這兩天看了公司的老程式碼,發現有大量的在用getattr….  雖然在不得已的時候,也會考慮用getattr,只是沒這麼頻繁而已….    

這邊的getattr主要是用在函式呼叫上,比如一個簡單的rpc服務,裡面註冊了N個函式,這時候,客戶端是知道自己需要呼叫哪個函式的,他給我傳遞了一個名字叫getName函式名,那麼我用getattr直接呼叫就OK了….

getattr是python裡的一個內建函式,在python的官方文件中:getattr()的解釋:

getattr(object, name[, default])

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, ‘foobar’) is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

getattr()這個方法最主要的作用是實現反射機制。也就是說可以通過字串獲取方法例項。這樣,你就可以把一個類可能要呼叫的方法放在配置檔案裡,在需要的時候動態載入。

python裡面跟getattr相關的有hasattr,setattr,delattr  ,那麼我們通過下面的例子,來詳細的說說他們的用法。 

Python

#!/usr/bin/python
class Xiaorui:

     def __init__(self):

        self.name = ‘fengyun’

    def setName(self,name):

        self.name = name

    def
getName(self):
return self.name def greet(self): print “Hello,i’m %s”%self.name foo = Xiaorui()

一. hasattr(object,name)

bool       判斷object中是否具有name屬性,例如:

foo = Xiaorui()

hasattr(foo,’setName’) #判斷setName是否存在,存在則返回True。

二. getattr(object,name,default)

如果存在name屬性(方法)則返回name的值(方法地址)否則返回default值。

getattr(foo,’name’,’NA’) #存在name屬性,所以返回其value

‘fengyun’

getattr(foo,’age’,’NA’)

‘NA’

一會發現,他其實跟直接object.name 用法一樣。 

三. setattr(object,name,default)

setattr(foo,’age’,’18’) #

字串可能會列出一個現有的屬性(或一個新的屬性)。這個函式將值賦給屬性的

.類似foo.age = 18

getattr(foo,’age’,’not find’)

’18’ 

setattr(foo,’work’,’student’) #

可以用setattr方法,把foo的work變數,設定為student

getattr(foo,’work’,’not find’)

‘student’

四. delattr(object,’name’)

delattr(foo,’name’)#刪除屬性name,原值為‘fengyun’

getattr(foo,’name’,’not find’)

‘not find’

今重點是getattr的用法, 我也不多說了,就簡單寫個例子,說明下,我一般是怎麼用getattr的。 

Python

#xiaorui.cc
import test

import multiprocessing

def run(func,*args):
#    print getattr(test, "hello")("hello", "world")
    print getattr(test, func)(*args)

pool = multiprocessing.Pool(processes=4)
for i in xrange(10):
    pool.apply_async(run, ('hello','hello','world' ))
    pool.apply_async(run, ('test_sleep','hello','world' ))
pool.close()
pool.join()
print "END from xiaorui.cc"

檔名是,  test.py

Python

import time

def hello(str1, str2):
    print 'hello'
    return [str1, str2]

def test_sleep(str1, str2):
    print 'test_sleep'
    time.sleep(3)
    return [str1, str2]
這個時候,我們可以定義一個字串,然後用getattr去執行,這樣呼叫效果有些類似python的celery那種用globals的用法。 我傳遞一個函式的名字,當然是字串,我可以用multiprocessing多程序呼叫這個方法。