详细讲述python自省函数getattr的用法

这两天看了公司的老代码,发现有大量的在用getattr….  虽然在不得已的时候,也会考虑用getattr,只是没这么频繁而已….    

这边的getattr主要是用在函数调用上,比如一个简单的rpc服务,里面注册了N个函数,这时候,客户端是知道自己需要调用哪个函数的,他给我传递了一个名字叫getName函数名,那么我用getattr直接调用就OK了….


关于python内建函数getattr的用法,文章出处 http://xiaorui.cc/?p=1798


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  ,那么我们通过下面的例子,来详细的说说他们的用法。 

#!/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的。 

#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

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多进程调用这个方法。 


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

发表评论

邮箱地址不会被公开。 必填项已用*标注