Python的反射机制可以动态获取对象信息以及动态调用对象,Python反射介绍 介绍了Python常用的反射函数使用方法,本文介绍如何获取对象中的函数注释信息以及参数信息。
定义一个Person类:
1 2 3 4 5 6 7 8 9 class Person (): def talk (self, name, age, height=None ): """talk function :return: """ print(f"My name is {name} " ) print(f"My age is {age} " ) if height is not None : print(f"My height is {height} " )
dir() 命令也可以获取函数的属性信息:1 2 3 4 5 person = Person() print(dir (person)) func = getattr (person, "talk" ) print(dir (func))
Out:1 2 3 4 ['__class__' , '__delattr__' , '__dict__' , '__dir__' , '__doc__' , '__eq__' , '__format__' , '__ge__' , '__getattribute__' , '__gt__' , '__hash__' , '__init__' , '__init_subclass__' , '__le__' , '__lt__' , '__module__' , '__ne__' , '__new__' , '__reduce__' , '__reduce_ex__' , '__repr__' , '__setattr__' , '__sizeof__' , '__str__' , '__subclasshook__' , '__weakref__' , 'talk' ] ['__call__' , '__class__' , '__delattr__' , '__dir__' , '__doc__' , '__eq__' , '__format__' , '__func__' , '__ge__' , '__get__' , '__getattribute__' , '__gt__' , '__hash__' , '__init__' , '__init_subclass__' , '__le__' , '__lt__' , '__ne__' , '__new__' , '__reduce__' , '__reduce_ex__' , '__repr__' , '__self__' , '__setattr__' , '__sizeof__' , '__str__' , '__subclasshook__' ]
获取函数注释信息 可以通过 __doc__ 属性来获取注释信息(三引号括起来的注释):
1 2 func = getattr (person, "talk" ) print(func.__doc__)
Out:
获取函数参数 1、 通过 __code__ 属性读取函数参数信息
1 2 >> print(dir (func.__code__)) ['__class__' , '__delattr__' , '__dir__' , '__doc__' , '__eq__' , '__format__' , '__ge__' , '__getattribute__' , '__gt__' , '__hash__' , '__init__' , '__init_subclass__' , '__le__' , '__lt__' , '__ne__' , '__new__' , '__reduce__' , '__reduce_ex__' , '__repr__' , '__setattr__' , '__sizeof__' , '__str__' , '__subclasshook__' , 'co_argcount' , 'co_cellvars' , 'co_code' , 'co_consts' , 'co_filename' , 'co_firstlineno' , 'co_flags' , 'co_freevars' , 'co_kwonlyargcount' , 'co_lnotab' , 'co_name' , 'co_names' , 'co_nlocals' , 'co_stacksize' , 'co_varnames' ]>>
1 2 3 4 5 6 7 8 print("co_name: " , func.__code__.co_name) print("co_argcount: " , func.__code__.co_argcount) print("co_varnames: " ,func.__code__.co_varnames) print("co_filename: " , func.__code__.co_filename) print("co_consts: " , func.__code__.co_consts) print("co_firstlineno: " ,func.__code__.co_firstlineno) print("co_kwonlyargcount: " ,func.__code__.co_kwonlyargcount) print("co_nlocals: " ,func.__code__.co_nlocals)
Out:
1 2 3 4 5 6 7 8 co_name: talk co_argcount: 4 co_varnames: ('self' , 'name' , 'age' , 'height' ) co_filename: D:/ProgramWorkspace/PythonNotes/00 -Python-Essentials/demo.py co_consts: ('talk function\n :return:\n ' , 'My name is ' , 'My age is ' , None , 'My height is ' ) co_firstlineno: 44 co_kwonlyargcount: 0 co_nlocals: 4
通过 __code__.co_varnames 可以获取参数名,参数默认值可以通过如下方式获得:
1 print(func.__defaults__)
Out:
2、通过inspect库来读取函数参数信息
除了用__code__ 属性外还可以使用inspect库来读取函数参数,使用getfullargspec和signature方法来读取函数参数:
1 2 3 4 5 6 7 8 9 import inspectargspec = inspect.getfullargspec(func) print(argspec.args) print(argspec.defaults) print(argspec.varkw) sig = inspect.signature(func) print(sig)
Out:
1 2 3 4 ['self' , 'name' , 'age' , 'height' ] (None ,) None (name, age, height=None )
也可以在函数内部使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Person (): def talk (self, name, age, height=None ): """talk function :return: """ frame = inspect.currentframe() args, _, _, values = inspect.getargvalues(frame) print(inspect.getframeinfo(frame)) print(f'function name: {inspect.getframeinfo(frame).function} ' ) for i in args: print(f"{i} = {values[i]} " ) if __name__ == '__main__' : p = Person() p.talk("zhangsan" , 18 , height=175 )
Out:
1 2 3 4 5 6 Traceback(filename='D:/ProgramWorkspace/PythonNotes/00-Python-Essentials/demo.py' , lineno=44 , function='talk' , code_context=[' print(inspect.getframeinfo(frame))\n' ], index=0 ) function name: talk self = <__main__.Person object at 0x0000023E4CF17B08 > name = zhangsan age = 18 height = 175
--THE END--