Python--反射
在python中,给你一个函数或者类的字符串名称,你怎么得到该函数和类,以下方式:
1.通过getattr获取方法名,再运行
class TestA(object): def get_test(self): print("我是函数1") def instance(self): print("我是函数2") ins = TestA() get_test = getattr(ins, "get_test") # 通过python的反射方法getattr达到我们想要的结果 get_test()
我们运行得到结果:
我是函数1
让我们getattr函数的源码
def getattr(object, name, default=None): # known special case of getattr """ getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. """ pass
根据源码解释getattr函数需要我们传一个对象,和一个字符串,然后从对象中找到和字符串同名的方法属性。
当然跟getattr相同的反射方法有,setattr和delattr,顾名思义这里不多解释。
2.通过eval函数
class TestA(object): def get_test(self): print("我是函数1") def instance(self): print("我是函数2") @staticmethod def test3(): print("我是静态方法") ins = TestA() instance = getattr(TestA, "instance") instance(ins) print("---------------2---------------------") eval("instance")(ins) print("-----------------3-------------------") eval("TestA").test3()
得到我们想要的结果,那我们就好奇eval函数是怎么实现可以传入一个字符串就去寻找对应的函数或者类对象,我们看一下eval函数的源码
def eval(source, globals=None, locals=None): # real signature unknown; restored from __doc__ """ eval(source[, globals[, locals]]) -> value Evaluate the source in the context of globals and locals. The source may be a string representing a Python expression or a code object as returned by compile(). The globals must be a dictionary and locals can be any mapping, defaulting to the current globals and locals. If only globals is given, locals defaults to it. """ pass
我们根据源码解释,首先解释器会我们传入的去locals和globals中去找我们传入的source为键找对应的值,如果未传入globals和locals就会去默认的glocals和locals中寻找,然后我们就好奇这个globals和locals是什么,然后我们运行一下
def globals(): # real signature unknown; restored from __doc__ """ globals() -> dictionary Return the dictionary containing the current scope's global variables. """ return {} def locals(): # real signature unknown; restored from __doc__ """ locals() -> dictionary Update and return a dictionary containing the current scope's local variables. """ return {}
看源码解释,globals为返回一个包含全局变量的字典,locals为返回一个包含本地变量的字典,然后运行这两个函数,看一下结果:
3.通过globals函数
globals()函数运行的结果为一个字典,类对象的字符串为建,类对象为值,所以我们可以这样得到:
class TestA(object): a=1 def get_test(self): print("我是函数1") def instance(self): print("我是函数2") @staticmethod def test3(): print("我是静态方法") globals()["TestA"].test3()
结果:
我是静态方法
4.通过标准库operator中methodcaller方法
from operator import methodcaller class Circle(object): def __init__(self, radius): self.radius = radius def getArea(self): return round(pow(self.radius, 2) * pi, 2) class Rectangle(object): def __init__(self, width, height): self.width = width self.height = height def get_area(self): return self.width * self.height if __name__ == '__main__': c1 = Circle(5.0) r1 = Rectangle(4.0, 5.0) # 第一个参数是函数字符串名字,后面是函数要求传入的参数,执行括号中传入对象 erea_c1 = methodcaller('getArea')(c1) erea_r1 = methodcaller('get_area')(r1) print(erea_c1, erea_r1)