Skip to content

Instantly share code, notes, and snippets.

@yyasuda
Last active May 18, 2016 08:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yyasuda/7cc6dd4e8332f1f16ec4 to your computer and use it in GitHub Desktop.
Save yyasuda/7cc6dd4e8332f1f16ec4 to your computer and use it in GitHub Desktop.
# 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
Copy link
Author

yyasuda commented Jan 19, 2016

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

@yyasuda
Copy link
Author

yyasuda commented Jan 21, 2016

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

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