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

Python是一門非常容易入門,但非常難以精通的一門編程語言渊跋。難在面向?qū)ο?繼承集合腊嗡、多態(tài)、組合等等)拾酝,難在抽象(設(shè)計模式)燕少,難在語法糖,難在元編程蒿囤,難在代碼可以非常非常靈活的組合客们。

當我遇到瓶頸需要通過閱讀大量框架代碼來提升編程水平的過程中,由于框架性代碼過于靈活或抽象,很多時候沒辦法僅通過閱讀源代碼就能理解底挫,而是需要加入日志去運行恒傻、調(diào)試來查看當前對象是什么類,當前對象有哪些屬性建邓,當前對象是被誰調(diào)用的盈厘。

下面分享兩個我在閱讀開源框架源碼時常用的分析工具:

裝飾器

查看調(diào)用者的文件位置路徑和代碼調(diào)用所在的行數(shù),通過這種方式我可以一層一層的追蹤代碼執(zhí)行的源頭在哪里官边。
也就是說一般使用它的場景是理解代碼線性處理過程沸手。

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())
輸出結(jié)果
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

參考網(wǎng)址:
Stansosleepy的簡書博客

?
?
?
?
?
?

內(nèi)省函數(shù)

很多時候開源框架的文檔并沒有細致到告訴你每一個方法是什么意思,怎么用注簿。
通常我在使用一個框架的某個組件功能時契吉,習(xí)慣看看調(diào)用某個方法返回的結(jié)果,并分析一下該結(jié)果對象中包含有哪些可調(diào)用的方法诡渴,每個方法綁定的是哪些類對象捐晶,通過這些屬性對象可以使我對整個框架的功能和理解更全面。

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

class ObjectAttrs(object):

    """
    一般用于調(diào)試某個對象時使用妄辩,當前這個工具類會將調(diào)試對象和其所屬的所有繼承對象的屬性依次羅列出來租悄。
    
    變量 showed_list 它是一個類變量, 用于記錄已顯示過的對象.
    
    使用方法:
    ObjectAttrs.show(調(diào)試對象)
    """

    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: 內(nèi)部使用的參數(shù), 用來傳遞_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: 僅顯示對象的所有繼承關(guān)系
import utils
utils.ObjectAttrs.show(Fox(), show_attr=False)
# 輸出結(jié)果
<__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)
# 輸出結(jié)果
<__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: 顯示當前對象的所有屬性 以及 顯示當前對象所有繼承關(guān)系
import utils
utils.ObjectAttrs.show(Fox())
# 輸出結(jié)果
<__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>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恩袱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胶哲,老刑警劉巖畔塔,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機谷市,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門贞铣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人凄吏,你說我怎么就攤上這事。” “怎么了桑阶?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勾邦。 經(jīng)常有香客問我蚣录,道長,這世上最難降的妖魔是什么眷篇? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任萎河,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虐杯。我一直安慰自己玛歌,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布擎椰。 她就那樣靜靜地躺著支子,像睡著了一般。 火紅的嫁衣襯著肌膚如雪确憨。 梳的紋絲不亂的頭發(fā)上译荞,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音休弃,去河邊找鬼吞歼。 笑死,一個胖子當著我的面吹牛塔猾,可吹牛的內(nèi)容都是我干的篙骡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丈甸,長吁一口氣:“原來是場噩夢啊……” “哼糯俗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睦擂,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤得湘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后顿仇,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淘正,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年臼闻,在試婚紗的時候發(fā)現(xiàn)自己被綠了鸿吆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡述呐,死狀恐怖惩淳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乓搬,我是刑警寧澤思犁,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站缤谎,受9級特大地震影響抒倚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坷澡,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一托呕、第九天 我趴在偏房一處隱蔽的房頂上張望含蓉。 院中可真熱鬧,春花似錦项郊、人聲如沸馅扣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽差油。三九已至,卻和暖如春任洞,著一層夾襖步出監(jiān)牢的瞬間蓄喇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工交掏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留妆偏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓盅弛,卻偏偏與公主長得像钱骂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挪鹏,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理见秽,服務(wù)發(fā)現(xiàn),斷路器讨盒,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,147評論 25 707
  • 跟孩子的聊天經(jīng)常是在晚飯的餐桌上解取。今天也不例外。兒子又跟我們說起他學(xué)校的趣事返顺,主題是關(guān)于英語: 那天我跟蘭浩聊起了...
    左左_88閱讀 165評論 0 0
  • 再濃烈的感情肮蛹,終有一日會歸于平淡。我們的虛擬愛情也不例外创南。 轟轟烈烈誠然可貴,可細水長流的溫潤更讓人舒服省核。 早上起...
    明初的日記本閱讀 239評論 0 0
  • 很多人稿辙,每天都在重復(fù),在這個重復(fù)的生活當中气忠,漸漸的忘卻了當初的目標邻储,失去了當初的斗志,更有甚者認為這就是人生旧噪!20...
    赤腳大爺閱讀 259評論 0 1