Python自省学习
1. 访问对象的属性
class MyClass(): a=‘1‘ b=‘2‘ def __init__(self): pass def write(self): print self.a,self.b myClass=MyClass() print dir(myClass) print dir(MyClass) print hasattr(MyClass,‘a‘) print getattr(MyClass,‘a‘) print setattr(MyClass,‘a‘,‘11‘) print getattr(MyClass,‘a‘)
输出:
[‘__doc__‘, ‘__init__‘, ‘__module__‘, ‘a‘, ‘b‘, ‘write‘] [‘__doc__‘, ‘__init__‘, ‘__module__‘, ‘a‘, ‘b‘, ‘write‘] True 1 None 11
访问对象属性的方法有,dir,hasattr,getattr,setattr
用setattr可以修改类的熟悉(不是实例),这个比较厉害。
import os class MyClass(): ‘‘‘ aaa ‘‘‘ a=‘1‘ b=‘2‘ def __init__(self): pass def write(self): print self.a,self.b myClass=MyClass() print dir(MyClass) print MyClass.__name__ #对象的名称 print MyClass.write.func_code #对象的代码 print MyClass.__doc__ #对象的文档 print MyClass.__dict__ #对象所有的属性和方法,与dir类似,但是格式是字典 print os.__file__ #对象所在的路径
输出:
[‘__doc__‘, ‘__init__‘, ‘__module__‘, ‘a‘, ‘b‘, ‘write‘] MyClass <code object write at 0000000001D71530, file "E:/myDemo/myDemo/?????/z1.py", line 13> aaa {‘a‘: ‘1‘, ‘__module__‘: ‘__main__‘, ‘b‘: ‘2‘, ‘write‘: <function write at 0x00000000025AEC18>, ‘__doc__‘: ‘\n aaa\n ‘, ‘__init__‘: <function __init__ at 0x00000000025AEBA8>} C:\Python27\lib\os.pyc
__doc__返回这个对象的文档,对象下面用三个引号括住的为文档
print isinstance(myClass,MyClass) #检验某实例对象是否是某个类型
总结:
方法或属性 | 作用 |
dir() | 返回一个对象拥有的方法和属性的列表 |
__dict__ | 返回一个对象拥有的方法和属性的字典 |
__name__ | 返回对象名称 |
__doc__ | 返回对象的文档 |
__self__ | 返回对象自身 |
__file__ | 返回对象的路径 |
__module__ | 返回对象所在的模块 |
__func__ | 返回对象的代码 |
__class__ | 返回对象的类 |
isinstace | 检验某实例对象是否是某个类型 |
2.代码块
•co_argcount: 普通参数的总数,不包括*参数和**参数。
•co_names: 所有的参数名(包括*参数和**参数)和局部变量名的元组。
•co_varnames: 所有的局部变量名的元组。
•co_filename: 源代码所在的文件名。
•co_flags: 这是一个数值,每一个二进制位都包含了特定信息。较关注的是0b100(0x4)和0b1000(0x8),如果co_flags & 0b100 != 0,说明使用了*args参数;如果co_flags & 0b1000 != 0,说明使用了**kwargs参数。另外,如果co_flags & 0b100000(0x20) != 0,则说明这是一个生成器函数(generator function)。
class MyClass(): ‘‘‘ aaa ‘‘‘ a=‘1‘ b=‘2‘ def __init__(self): pass def write(self,c,d): print self.a,self.b myClass=MyClass() print MyClass.write.func_code.co_argcount # 3 print MyClass.write.func_code.co_names # (‘a‘, ‘b‘) print MyClass.write.func_code.co_varnames # (‘self‘, ‘c‘, ‘d‘) print MyClass.write.func_code.co_filename # E:/myDemo/myDemo/?????/z2.py
3.栈帧(frame)
•f_back: 调用栈的前一帧。
•f_code: 栈帧对应的code对象。
•f_locals: 用在当前栈帧时与内建函数locals()相同,但你可以先获取其他帧然后使用这个属性获取那个帧的locals()。
•f_globals: 用在当前栈帧时与内建函数globals()相同,但你可以先获取其他帧……。
import inspect def add(x, y=1): f = inspect.currentframe() print f.f_locals # {‘y‘: 1, ‘x‘: 2, ‘f‘: <frame object at 0x00000000026C19B8>} print f.f_globals #返回全局变量 {‘__builtins__‘: <module ‘__builtin__‘ (built-in)>, ‘__file__‘:
‘E:/myDemo/myDemo/\xd7\xd4\xca\xa1\xd1\xa7\xcf\xb0/z2.py‘, ‘inspect‘: <module ‘inspect‘ from ‘C:\Python27\lib\inspect.pyc‘>,
‘__author__‘: ‘[email protected]‘, ‘add‘: <function add at 0x00000000026C2518>, ‘__name__‘: ‘__main__‘, ‘__package__‘: None,
‘os‘: <module ‘os‘ from ‘C:\Python27\lib\os.pyc‘>, ‘__doc__‘: None} print f.f_code # <code object add at 0000000001DD6E30, file "E:/myDemo/myDemo/?????/z2.py", line 6> print f.f_back # <frame object at 0x00000000025D01C8> return x+y add(2)
4.追踪
•tb_next: 追踪的下一个追踪对象。
•tb_frame: 当前追踪对应的栈帧。
•tb_lineno: 当前追踪的行号。
import sys def div(x, y): try: return x/y except: tb = sys.exc_info()[2] # return (exc_type, exc_value, traceback) print tb print tb.tb_lineno # "return x/y" 的行号 6 print tb.tb_frame.f_locals #返回跳出程序时的栈帧 {‘y‘: 0, ‘x‘: 1, ‘tb‘: <traceback object at 0x000000000271FE88>} div(1, 0)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。