Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# coding: UTF-8
""" Monitoring """
class Monitoring(dict):
@classmethod
def _printCodeInfo(cls, cur_frame):
import inspect
bac_frame = cur_frame.f_back # この関数の呼び出し元のフレームオブジェクトを取得。
bac_frame_co = bac_frame.f_code
# print("呼び出し元関数名 = {}".format(bac_frame_co.co_name))
bac_frame_info = inspect.getframeinfo(bac_frame) # フレームオブジェクトのフレームレコードを取得。
# print("そのフレームレコードから得たソースコードのリスト = {}".format(bac_frame_info.code_context))
# print("そのフレームから得た行番号 = {}".format(bac_frame.f_lineno))
print('@@ %03d : func %s - %s' % (bac_frame.f_lineno, bac_frame_co.co_name, bac_frame_info.code_context))
#print('==== %x' % (id(bac_frame_co.__self__)))
#print("cur local variables {}".format(cur_frame.f_locals))
#print("bac local variables {}".format(bac_frame.f_locals))
@classmethod
def _printStackInfo(cls, label):
import inspect
framerecords = inspect.stack()
# print(" == stack {}".format(framerecords))
if len(framerecords) > 2 :
framerecord = framerecords[2] # 呼び出し元フレーム
arginfo = inspect.getargvalues(framerecord[0]) # 呼び出し元(先頭)から引き数情報を取得
if 'self' in arginfo.locals:
print(" >>>> %s id = %x " % (label, id(arginfo.locals['self'])))
else:
print(" >>>> %s NONE" % label)
@classmethod
def printArgInfo(cls, *args):
# print("@@@@@ args = %s" % format(args))
for arg in args:
if(isinstance(arg, Monitoring)):
print('called_with: id = %x' % id(arg))
else:
print('called_with: value = %s %s ' % (format(arg), type(arg)))
def __new__(cls, *args):
import inspect
cls._printCodeInfo(inspect.currentframe())
# print('called __new__: id = %x %s' % (id(cls), format(cls)))
print('called __new__: id = %x (%s)' % (id(cls), cls.__name__))
cls._printStackInfo('sender')
obj = super(Monitoring, cls).__new__(cls, args)
print(' >>>> instance id = %x' % id(obj))
return obj
def __getattr__(self, key):
import inspect
self.__class__._printCodeInfo(inspect.currentframe())
value = self.__getitem__(key)
if(isinstance(value, Monitoring)):
print('called __getattr__: id = %x (%s, %s = id %x)' % (id(self), key, value, id(value)))
else:
print('called __getattr__: id = %x (%s, %s = %s)' % (id(self), key, value, type(value)))
self.__class__._printStackInfo('run_on')
return value
def __setattr__(self, key, value):
import inspect
self.__class__._printCodeInfo(inspect.currentframe())
result = self.__setitem__(key, value)
if(isinstance(value, Monitoring)):
print('called __setattr__: id = %x (%s, %s = id %x)' % (id(self), key, value, id(value)))
else:
print('called __setattr__: id = %x (%s, %s = %s)' % (id(self), key, value, type(value)))
self.__class__._printStackInfo('run_on')
return result
def __getattribute__(self, key):
# print("====================== key = %s" % (key))
if key == '__getitem__': # これは getter アクセスの副作用
pass
v = object.__getattribute__(self, key)
if key == 'printCodeInfo':
return v.__get__(None, self) # 内部処理はフィルタする
if hasattr(v, '__get__'):
import inspect
self.__class__._printCodeInfo(inspect.currentframe())
print('called __getattribute__: id = %x (%s AS function)' % (id(self), key))
self.__class__._printStackInfo('sender')
return v.__get__(None, self)
if key == '__getitem__': # これは getter アクセスの副作用
pass
elif key == '__setitem__': # これは setter アクセスの副作用
pass
elif key == '__class__': # これは上の printCodeInfo を呼び出すための __class__ 呼び出しの副作用
pass
else:
print('called __getattribute__: id = %x (%s AS variable)' % (id(self), key))
return v
# ================ トレースする対象となるオブジェクト
class Foo(Monitoring):
def __init__(self):
print "--------"
self.bar = Bar()
print "--------"
print self.bar.a
print "--------"
self.bar.pr()
print "--------"
self.a = 0 # Foo
class Bar(Monitoring):
def __init__(self):
self.a = 0 # Bar
def pr(self):
print "- 123 -"
class Boo(Monitoring):
def pr(self):
print "test"
# ================ ここから主プログラム
print("##########")
obj1 = Foo()
print("##########")
print(obj1.a)
print("##########")
obj2 = Boo()
obj2 = Boo()
print("##########")
@yyasuda

This comment has been minimized.

Copy link
Owner Author

@yyasuda yyasuda commented Jan 19, 2016

まあこれだけじゃあ何のことか分からないでしょうが、、、ともかく実行結果を。。。

##########
@@ 125 : func <module> - ['obj1 = Foo()\n']
called __new__: id = 7fad0b507860 (Foo)
    >>>> sender NONE
    >>>> instance id = 10e80fbe0
--------
@@ 103 : func __init__ - ['        self.bar = Bar()\n']
called __new__: id = 7fad0b507c10 (Bar)
    >>>> sender id = 10e80fbe0 
    >>>> instance id = 10e80fd08
@@ 113 : func __init__ - ['        self.a = 0 # Bar\n']
called __setattr__: id = 10e80fd08 (a, 0 = <type 'int'>)
    >>>> run_on id = 10e80fd08 
@@ 103 : func __init__ - ['        self.bar = Bar()\n']
called __setattr__: id = 10e80fbe0 (bar, {'a': 0} = id 10e80fd08)
    >>>> run_on id = 10e80fbe0 
--------
@@ 105 : func __init__ - ['        print self.bar.a\n']
called __getattr__: id = 10e80fbe0 (bar, {'a': 0} = id 10e80fd08)
    >>>> run_on id = 10e80fbe0 
@@ 105 : func __init__ - ['        print self.bar.a\n']
called __getattr__: id = 10e80fd08 (a, 0 = )
    >>>> run_on id = 10e80fbe0 
0
--------
@@ 107 : func __init__ - ['        self.bar.pr()\n']
called __getattr__: id = 10e80fbe0 (bar, {'a': 0} = id 10e80fd08)
    >>>> run_on id = 10e80fbe0 
@@ 107 : func __init__ - ['        self.bar.pr()\n']
called __getattribute__: id = 10e80fd08 (pr AS function)
    >>>> sender id = 10e80fbe0 
- 123 -
--------
@@ 109 : func __init__ - ['        self.a = 0 # Foo\n']
called __setattr__: id = 10e80fbe0 (a, 0 = )
    >>>> run_on id = 10e80fbe0 
##########
@@ 127 : func  - ['print(obj1.a)\n']
called __getattr__: id = 10e80fbe0 (a, 0 = )
    >>>> run_on NONE
0
##########
@@ 129 : func  - ['obj2 = Boo()\n']
called __new__: id = 7fad0b507fc0 (Boo)
    >>>> sender NONE
    >>>> instance id = 10e80fe30
@@ 130 : func  - ['obj2 = Boo()\n']
called __new__: id = 7fad0b507fc0 (Boo)
    >>>> sender NONE
    >>>> instance id = 10e9a9050
##########

これでつまり実行時のオブジェクトへのアクセスをログに残して、これを可視化してやろうというわけです。。。

@yyasuda

This comment has been minimized.

Copy link
Owner Author

@yyasuda yyasuda commented Jan 19, 2016

sample8_01

@yyasuda

This comment has been minimized.

Copy link
Owner Author

@yyasuda yyasuda commented Jan 19, 2016

もひとつ。実際のコードとの対照はこんな感じ。
sample8_01x

@yyasuda

This comment has been minimized.

Copy link
Owner Author

@yyasuda yyasuda commented Jan 21, 2016

なお上のダイアグラム的な図は手描き。ソースコードとの対照図も手描きです。
あくまで学生向けの説明資料。。。。頑張って実装してくれると良いのだけれど。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment