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>
<class '__main__.Fox'> inherited by <__main__.Fox object at 0x035D2B30>
<class '__main__.Base'> inherited by <class '__main__.Fox'>
使用方法2: 仅显示当前对象的所有属性
import utils
utils.ObjectAttrs.show(Fox(), show_parent=False)
# 输出结果
<__main__.Fox object at 0x030F2910>
__class__                                                   <type 'type'>                                               <class '__main__.Fox'>
__delattr__                                                 error
__dict__                                                    <type 'dict'>                                               {'name': 'aurora fox', 'actions': <__main__.FoxManager object at 0x030F2F50>, 'sex': 'male'}
__format__                                                  <type 'builtin_function_or_method'>                         <built-in method __format__ of Fox object at 0x030F2910>
__getattribute__                                            error
__hash__                                                    error
__init__                                                    <type 'instancemethod'>                                     <bound method Fox.__init__ of <__main__.Fox object at 0x030F2910>>
__module__                                                  <type 'str'>                                                __main__
__new__                                                     <type 'builtin_function_or_method'>                         <built-in method __new__ of type object at 0x51FA68B8>
__reduce__                                                  <type 'builtin_function_or_method'>                         <built-in method __reduce__ of Fox object at 0x030F2910>
__reduce_ex__                                               <type 'builtin_function_or_method'>                         <built-in method __reduce_ex__ of Fox object at 0x030F2910>
__repr__                                                    error
__setattr__                                                 error
__sizeof__                                                  <type 'builtin_function_or_method'>                         <built-in method __sizeof__ of Fox object at 0x030F2910>
__str__                                                     error
__subclasshook__                                            <type 'builtin_function_or_method'>                         <built-in method __subclasshook__ of type object at 0x030F9968>
__weakref__                                                 <type 'NoneType'>                                           None
actions                                                     <class '__main__.FoxManager'>                               <__main__.FoxManager object at 0x030F2F50>
name                                                        <type 'str'>                                                aurora fox
run                                                         <type 'instancemethod'>                                     <bound method Fox.run of <__main__.Fox object at 0x030F2910>>
sex                                                         <type 'str'>                                                male
sleep                                                       <type 'instancemethod'>                                     <bound method Fox.sleep of <__main__.Fox object at 0x030F2910>>
walk                                                        <type 'instancemethod'>                                     <bound method Fox.walk of <__main__.Fox object at 0x030F2910>>
使用方法3: 显示当前对象的所有属性 以及 显示当前对象所有继承关系
import utils
utils.ObjectAttrs.show(Fox())
# 输出结果
<__main__.Fox object at 0x02ED2B50>
__class__                                                   <type 'type'>                                               <class '__main__.Fox'>
__delattr__                                                 error
__dict__                                                    <type 'dict'>                                               {'name': 'aurora fox', 'actions': <__main__.FoxManager object at 0x02ED2F50>, 'sex': 'male'}
__format__                                                  <type 'builtin_function_or_method'>                         <built-in method __format__ of Fox object at 0x02ED2B50>
__getattribute__                                            error
__hash__                                                    error
__init__                                                    <type 'instancemethod'>                                     <bound method Fox.__init__ of <__main__.Fox object at 0x02ED2B50>>
__module__                                                  <type 'str'>                                                __main__
__new__                                                     <type 'builtin_function_or_method'>                         <built-in method __new__ of type object at 0x51FA68B8>
__reduce__                                                  <type 'builtin_function_or_method'>                         <built-in method __reduce__ of Fox object at 0x02ED2B50>
__reduce_ex__                                               <type 'builtin_function_or_method'>                         <built-in method __reduce_ex__ of Fox object at 0x02ED2B50>
__repr__                                                    error
__setattr__                                                 error
__sizeof__                                                  <type 'builtin_function_or_method'>                         <built-in method __sizeof__ of Fox object at 0x02ED2B50>
__str__                                                     error
__subclasshook__                                            <type 'builtin_function_or_method'>                         <built-in method __subclasshook__ of type object at 0x02ED9968>
__weakref__                                                 <type 'NoneType'>                                           None
actions                                                     <class '__main__.FoxManager'>                               <__main__.FoxManager object at 0x02ED2F50>
name                                                        <type 'str'>                                                aurora fox
run                                                         <type 'instancemethod'>                                     <bound method Fox.run of <__main__.Fox object at 0x02ED2B50>>
sex                                                         <type 'str'>                                                male
sleep                                                       <type 'instancemethod'>                                     <bound method Fox.sleep of <__main__.Fox object at 0x02ED2B50>>
walk                                                        <type 'instancemethod'>                                     <bound method Fox.walk of <__main__.Fox object at 0x02ED2B50>>





<class '__main__.Fox'> inherited by <__main__.Fox object at 0x02ED2B50>
__class__                                                   <type 'type'>                                               <type 'type'>
__delattr__                                                 <type 'wrapper_descriptor'>                                 <slot wrapper '__delattr__' of 'object' objects>
__dict__                                                    <type 'dictproxy'>                                          {'__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x02ECBCB0>}
__format__                                                  error
__getattribute__                                            <type 'wrapper_descriptor'>                                 <slot wrapper '__getattribute__' of 'object' objects>
__hash__                                                    <type 'wrapper_descriptor'>                                 <slot wrapper '__hash__' of 'object' objects>
__init__                                                    <type 'instancemethod'>                                     <unbound method Fox.__init__>
__module__                                                  <type 'str'>                                                __main__
__new__                                                     <type 'builtin_function_or_method'>                         <built-in method __new__ of type object at 0x51FA68B8>
__reduce__                                                  error
__reduce_ex__                                               error
__repr__                                                    <type 'wrapper_descriptor'>                                 <slot wrapper '__repr__' of 'object' objects>
__setattr__                                                 <type 'wrapper_descriptor'>                                 <slot wrapper '__setattr__' of 'object' objects>
__sizeof__                                                  error
__str__                                                     <type 'wrapper_descriptor'>                                 <slot wrapper '__str__' of 'object' objects>
__subclasshook__                                            <type 'builtin_function_or_method'>                         <built-in method __subclasshook__ of type object at 0x02ED9968>
__weakref__                                                 <type 'getset_descriptor'>                                  <attribute '__weakref__' of 'Base' objects>
run                                                         <type 'instancemethod'>                                     <unbound method Fox.run>
sleep                                                       <type 'instancemethod'>                                     <unbound method Fox.sleep>
walk                                                        <type 'instancemethod'>                                     <unbound method Fox.walk>





<class '__main__.Base'> inherited by <class '__main__.Fox'>
__class__                                                   <type 'type'>                                               <type 'type'>
__delattr__                                                 <type 'wrapper_descriptor'>                                 <slot wrapper '__delattr__' of 'object' objects>
__dict__                                                    <type 'dictproxy'>                                          {'__module__': '__main__', 'run': <function run at 0x02ECBBB0>, 'walk': <function walk at 0x02ECBBF0>, 'sleep': <function sleep at 0x02ECBC30>, '__dict__': <attribute '__dict__' of 'Base' objects>, '__weakref__': <attribute '__weakref__' of 'Base' objects>, '__doc__': None}
__format__                                                  error
__getattribute__                                            <type 'wrapper_descriptor'>                                 <slot wrapper '__getattribute__' of 'object' objects>
__hash__                                                    <type 'wrapper_descriptor'>                                 <slot wrapper '__hash__' of 'object' objects>
__init__                                                    <type 'wrapper_descriptor'>                                 <slot wrapper '__init__' of 'object' objects>
__module__                                                  <type 'str'>                                                __main__
__new__                                                     <type 'builtin_function_or_method'>                         <built-in method __new__ of type object at 0x51FA68B8>
__reduce__                                                  error
__reduce_ex__                                               error
__repr__                                                    <type 'wrapper_descriptor'>                                 <slot wrapper '__repr__' of 'object' objects>
__setattr__                                                 <type 'wrapper_descriptor'>                                 <slot wrapper '__setattr__' of 'object' objects>
__sizeof__                                                  error
__str__                                                     <type 'wrapper_descriptor'>                                 <slot wrapper '__str__' of 'object' objects>
__subclasshook__                                            <type 'builtin_function_or_method'>                         <built-in method __subclasshook__ of type object at 0x02ED95B8>
__weakref__                                                 <type 'getset_descriptor'>                                  <attribute '__weakref__' of 'Base' objects>
run                                                         <type 'instancemethod'>                                     <unbound method Base.run>
sleep                                                       <type 'instancemethod'>                                     <unbound method Base.sleep>
walk                                                        <type 'instancemethod'>                                     <unbound method Base.walk>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 跟孩子的聊天经常是在晚饭的餐桌上。今天也不例外。儿子又跟我们说起他学校的趣事,主题是关于英语: 那天我跟兰浩聊起了...
    左左_88阅读 137评论 0 0
  • 再浓烈的感情,终有一日会归于平淡。我们的虚拟爱情也不例外。 轰轰烈烈诚然可贵,可细水长流的温润更让人舒服。 早上起...
    明初的日记本阅读 216评论 0 0
  • 很多人,每天都在重复,在这个重复的生活当中,渐渐的忘却了当初的目标,失去了当初的斗志,更有甚者认为这就是人生!20...
    赤脚大爷阅读 244评论 0 1