djangoソース分析--00ソース分析ツール
18084 ワード
Pythonは非常に入門しやすいが、非常に精通しにくいプログラミング言語である.オブジェクト向け(継承集合、多態、組合せなど)、抽象(設計モード)、文法糖、メタプログラミング、コードの非常に柔軟な組み合わせが難しい.
私がボトルネックに直面して大量のフレームワークコードを読むことでプログラミングレベルを向上させる必要がある過程で、フレームワークコードが柔軟すぎるか抽象的であるため、ソースコードを読むだけで理解できないことが多いが、ログを加えて実行し、デバッグして現在の対象がどのようなクラスであるか、現在のオブジェクトにどのような属性があり、現在のオブジェクトが誰によって呼び出されているかを見る必要がある.
オープンソースフレームワークのソースコードを読むときによく使う2つの分析ツールを共有します.
デコレーション
呼び出し元のファイル位置パスとコード呼び出しが存在する行数を表示します.これにより、コード実行のソースがどこにあるかを1つ1つ追跡できます.すなわち,一般に用いられるシーンは,コード線形処理過程を理解することである.
utils.py
使用方法
earth.py
出力結果
参考URL:Stansosleepyのブログ
内省関数
多くの場合、オープンソースフレームワークのドキュメントは、それぞれの方法がどういう意味なのか、どのように使われているのかを教えてくれません.通常、フレームワークのコンポーネント機能を使用するときは、メソッドを呼び出して返された結果を見て、その結果オブジェクトにどの呼び出し可能なメソッドが含まれているか、各メソッドがバインドされているクラスオブジェクトを分析することに慣れています.これらのプロパティオブジェクトを使用すると、フレームワーク全体の機能と理解をより全面的にすることができます.
utils.py
ソースファイル
fox.py
使用方法1:オブジェクトのすべての継承関係のみを表示
使用方法2:現在のオブジェクトのすべてのプロパティのみを表示
使用方法3:現在のオブジェクトのすべてのプロパティを表示し、現在のオブジェクトのすべての継承関係を表示します.
私がボトルネックに直面して大量のフレームワークコードを読むことでプログラミングレベルを向上させる必要がある過程で、フレームワークコードが柔軟すぎるか抽象的であるため、ソースコードを読むだけで理解できないことが多いが、ログを加えて実行し、デバッグして現在の対象がどのようなクラスであるか、現在のオブジェクトにどのような属性があり、現在のオブジェクトが誰によって呼び出されているかを見る必要がある.
オープンソースフレームワークのソースコードを読むときによく使う2つの分析ツールを共有します.
デコレーション
呼び出し元のファイル位置パスとコード呼び出しが存在する行数を表示します.これにより、コード実行のソースがどこにあるかを1つ1つ追跡できます.すなわち,一般に用いられるシーンは,コード線形処理過程を理解することである.
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
参考URL: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 = '
' * 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="">
inherited by <__main__.fox object="" at="">
inherited by
使用方法2:現在のオブジェクトのすべてのプロパティのみを表示
import utils
utils.ObjectAttrs.show(Fox(), show_parent=False)
#
<__main__.fox object="" at="">
__class__
__delattr__ error
__dict__ {'name': 'aurora fox', 'actions': <__main__.foxmanager object="" at="">, '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="">
name aurora fox
run >
sex male
sleep >
walk >
使用方法3:現在のオブジェクトのすべてのプロパティを表示し、現在のオブジェクトのすべての継承関係を表示します.
import utils
utils.ObjectAttrs.show(Fox())
#
<__main__.fox object="" at="">
__class__
__delattr__ error
__dict__ {'name': 'aurora fox', 'actions': <__main__.foxmanager object="" at="">, '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="">
name aurora fox
run >
sex male
sleep >
walk >
inherited by <__main__.fox object="" at="">
__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