首页 > 代码库 > Python自省学习

Python自省学习

1. 访问对象的属性

class MyClass():    a=1    b=2    def __init__(self):        pass    def write(self):        print self.a,self.bmyClass=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]True1None11

 

访问对象属性的方法有,dir,hasattr,getattr,setattr

用setattr可以修改类的熟悉(不是实例),这个比较厉害。

import osclass MyClass():    ‘‘‘    aaa    ‘‘‘    a=1    b=2    def __init__(self):        pass    def write(self):        print self.a,self.bmyClass=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.bmyClass=MyClass()print MyClass.write.func_code.co_argcount  # 3print 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 inspectdef 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__‘: ‘kevinlu1010@qq.com‘, ‘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+yadd(2)

4.追踪

•tb_next: 追踪的下一个追踪对象。

•tb_frame: 当前追踪对应的栈帧。

•tb_lineno: 当前追踪的行号。

import sysdef 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)

 

 

参考:http://developer.51cto.com/art/201101/242703.htm