django源码分析--00源码分析工具

Python是一门非常容易入门,但非常难以精通的一门编程语言。难在面向对象(继承集合、多态、组合等等),难在抽象(设计模式),难在语法糖,难在元编程,难在代码可以非常非常灵活的组合。

当我遇到瓶颈需要通过阅读大量框架代码来提升编程水平的过程中,由于框架性代码过于灵活或抽象,很多时候没办法仅通过阅读源代码就能理解,而是需要加入日志去运行、调试来查看当前对象是什么类,当前对象有哪些属性,当前对象是被谁调用的。

下面分享两个我在阅读开源框架源码时常用的分析工具:

装饰器

查看调用者的文件位置路径和代码调用所在的行数,通过这种方式我可以一层一层的追踪代码执行的源头在哪里。
也就是说一般使用它的场景是理解代码线性处理过程。

utils.py
# -.- coding:utf-8 -.-
from __future__ import print_function


def findcaller(func):
    def wrapper(*args,**kwargs):
        import sys
        f=sys._getframe()
        filename=f.f_back.f_code.co_filename
        lineno=f.f_back.f_lineno
        print('{} {!s:<20} {} {} {} {} {}'.format(func.func_name, 'Called By ', filename, '', lineno, args, kwargs))
        return func(*args,**kwargs)
    return wrapper
使用方法
earth.py
# -.- coding:utf-8 -.-
import utils


@utils.findcaller
def golden():
    return 'metal'


@utils.findcaller
def wood():
    return golden()


@utils.findcaller
def water():
    return wood()


@utils.findcaller
def fire():
    return water()


@utils.findcaller
def land():
    return fire()


print(land())
输出结果
land Called By            C:/Users/zhengtong/earth.py  31 () {}
fire Called By            C:/Users/zhengtong/earth.py  28 () {}
water Called By            C:/Users/zhengtong/earth.py  23 () {}
wood Called By            C:/Users/zhengtong/earth.py  18 () {}
golden Called By            C:/Users/zhengtong/earth.py  13 () {}
metal

参考网址:
Stansosleepy的博客

 
 
 
 
 
 

内省函数

很多时候开源框架的文档并没有细致到告诉你每一个方法是什么意思,怎么用。
通常我在使用一个框架的某个组件功能时,习惯看看调用某个方法返回的结果,并分析一下该结果对象中包含有哪些可调用的方法,每个方法绑定的是哪些类对象,通过这些属性对象可以使我对整个框架的功能和理解更全面。

utils.py
# -.- coding:utf-8 -.-
from __future__ import print_function

class ObjectAttrs(object):

    """
    一般用于调试某个对象时使用,当前这个工具类会将调试对象和其所属的所有继承对象的属性依次罗列出来。
    
    变量 showed_list 它是一个类变量, 用于记录已显示过的对象.
    
    使用方法:
    ObjectAttrs.show(调试对象)
    """

    showed_list = []

    @classmethod
    def show(cls, _class, show_attr=True, show_doc=False, _parent_class=None):
        """
        :param _class: 必填, 任意对象. 
        :param show_attr: 是否显示_class对象的所有attribute.                 
        :param show_doc: 是否显示_class对象的__doc__属性.
        :param _parent_class: 内部使用的参数, 用来传递_class对象的父类.                 
        :return: 
        """

        def _show(class_name):
            if class_name in cls.showed_list:
                return
            else:
                cls.showed_list.append(class_name)

            parent_class_name = ' inherited by {}'.format(_parent_class) if _parent_class else ''
            blank_lines = '\n' * 5 if show_attr else ''
            print(blank_lines, class_name, parent_class_name, sep='')

            if not show_attr: return

            for x in dir(class_name):
                if not show_doc:
                    if x == '__doc__':
                        continue
                try:
                    attr_name = x
                    attr_type = type(getattr(class_name, attr_name))
                    attr_object = getattr(class_name, attr_name)
                    print('{!s:<60}{!s:<60}{}'.format(attr_name, attr_type, attr_object))
                except:
                    print('{!s:<60}{}'.format(attr_name, 'error'))

        _show(class_name=_class)

        parents = list(getattr(_class, '__bases__', ''))
        parents.append(getattr(_class, '__class__', ''))
        parents = [i for i in parents if i is not object and i is not type and i]

        for i in parents:
            cls.show(_class=i, _parent_class=_class, show_doc=show_doc, show_attr=show_attr)
源代码文件
fox.py
# -.- coding:utf-8 -.-
import utils


class Base(object):

    def breathe(self):
        return 'breathe'


class Animal(Base):

    def run(self):
        return 'run'

    def walk(self):
        return 'walk'

    def sleep(self):
        return 'sleep'


class FoxManager(object):

    def find_other_fox(self):
        return 'find_other_fox'
        
    def drink(self):
        return 'drink water'
        
    def eat(self):
        return 'eat meat'


class Fox(Base):

    def __init__(self):
        self.name = 'aurora fox'
        self.sex = 'male'
        self.actions = FoxManager()
        
使用方法1: 仅显示对象的所有继承关系
import utils
utils.ObjectAttrs.show(Fox(), show_attr=False)
# 输出结果
<__main__.Fox object at 0x035D2B30>
 inherited by <__main__.Fox object at 0x035D2B30>
 inherited by 
使用方法2: 仅显示当前对象的所有属性
import utils
utils.ObjectAttrs.show(Fox(), show_parent=False)
# 输出结果
<__main__.Fox object at 0x030F2910>
__class__                                                                                                  
__delattr__                                                 error
__dict__                                                                                                   {'name': 'aurora fox', 'actions': <__main__.FoxManager object at 0x030F2F50>, 'sex': 'male'}
__format__                                                                           
__getattribute__                                            error
__hash__                                                    error
__init__                                                                                         >
__module__                                                                                                  __main__
__new__                                                                              
__reduce__                                                                           
__reduce_ex__                                                                        
__repr__                                                    error
__setattr__                                                 error
__sizeof__                                                                           
__str__                                                     error
__subclasshook__                                                                     
__weakref__                                                                                            None
actions                                                                                    <__main__.FoxManager object at 0x030F2F50>
name                                                                                                        aurora fox
run                                                                                              >
sex                                                                                                         male
sleep                                                                                            >
walk                                                                                             >
使用方法3: 显示当前对象的所有属性 以及 显示当前对象所有继承关系
import utils
utils.ObjectAttrs.show(Fox())
# 输出结果
<__main__.Fox object at 0x02ED2B50>
__class__                                                                                                  
__delattr__                                                 error
__dict__                                                                                                   {'name': 'aurora fox', 'actions': <__main__.FoxManager object at 0x02ED2F50>, 'sex': 'male'}
__format__                                                                           
__getattribute__                                            error
__hash__                                                    error
__init__                                                                                         >
__module__                                                                                                  __main__
__new__                                                                              
__reduce__                                                                           
__reduce_ex__                                                                        
__repr__                                                    error
__setattr__                                                 error
__sizeof__                                                                           
__str__                                                     error
__subclasshook__                                                                     
__weakref__                                                                                            None
actions                                                                                    <__main__.FoxManager object at 0x02ED2F50>
name                                                                                                        aurora fox
run                                                                                              >
sex                                                                                                         male
sleep                                                                                            >
walk                                                                                             >





 inherited by <__main__.Fox object at 0x02ED2B50>
__class__                                                                                                  
__delattr__                                                                                  
__dict__                                                                                              {'__module__': '__main__', '__doc__': None, '__init__': }
__format__                                                  error
__getattribute__                                                                             
__hash__                                                                                     
__init__                                                                                         
__module__                                                                                                  __main__
__new__                                                                              
__reduce__                                                  error
__reduce_ex__                                               error
__repr__                                                                                     
__setattr__                                                                                  
__sizeof__                                                  error
__str__                                                                                      
__subclasshook__                                                                     
__weakref__                                                                                   
run                                                                                              
sleep                                                                                            
walk                                                                                             





 inherited by 
__class__                                                                                                  
__delattr__                                                                                  
__dict__                                                                                              {'__module__': '__main__', 'run': , 'walk': , 'sleep': , '__dict__': , '__weakref__': , '__doc__': None}
__format__                                                  error
__getattribute__                                                                             
__hash__                                                                                     
__init__                                                                                     
__module__                                                                                                  __main__
__new__                                                                              
__reduce__                                                  error
__reduce_ex__                                               error
__repr__                                                                                     
__setattr__                                                                                  
__sizeof__                                                  error
__str__                                                                                      
__subclasshook__                                                                     
__weakref__                                                                                   
run                                                                                              
sleep                                                                                            
walk                                                                                             

你可能感兴趣的:(django源码分析--00源码分析工具)