Skip to content

Instantly share code, notes, and snippets.

@yyasuda
Last active April 27, 2025 08:55
Show Gist options
  • Select an option

  • Save yyasuda/7cc6dd4e8332f1f16ec4 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
Author

yyasuda commented Jan 21, 2016

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

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