Last active
November 18, 2015 09:04
-
-
Save yyasuda/867b4b555724dd28f415 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: UTF-8 | |
""" 非常に簡単なサンプル """ | |
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("@@ %03d : func %s - %s" % (bac_frame.f_lineno, bac_frame_co.co_name, bac_frame_info.code_context)) | |
#print("cur local variables {}".format(cur_frame.f_locals)) | |
print("bac local variables {}".format(bac_frame.f_locals)) | |
def __new__(cls, initial={}): | |
import inspect | |
cls._printCodeInfo(inspect.currentframe()) | |
print('called __new__:') | |
obj = super(Monitoring, cls).__new__(cls, initial={}) | |
print(" >>>> instance id = %s" % id(obj)) | |
return obj | |
def __getattr__(self, key): | |
value = self.__getitem__(key) | |
import inspect | |
self.__class__._printCodeInfo(inspect.currentframe()) | |
print('called __getattr__: id = %s (%s, %s = %s)' % (id(self), key, value, type(value))) | |
return value | |
def __setattr__(self, key, value): | |
import inspect | |
self.__class__._printCodeInfo(inspect.currentframe()) | |
result = self.__setitem__(key, value) | |
print('called __setattr__: id = %s (%s, %s = %s)' % (id(self), key, value, type(value))) | |
return result | |
def __getattribute__(self, key): | |
#print("====================== key = %s" % (key)) | |
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 = %s (%s AS function)' % (id(self), key)) | |
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 = %s (%s AS variable)' % (id(self), key)) | |
return v | |
# ================ トレースする対象となるオブジェクト | |
class Foo(Monitoring): | |
def __init__(self, x): | |
#print("__init__ called ") | |
self.a = x | |
def add(self, x): | |
self.a += x | |
# ================ ここから主プログラム | |
print("##########") | |
obj1 = Foo(100) | |
print(" obj1 id = %s" % id(obj1) ) | |
obj2 = Foo(200) | |
print(" obj2 id = %s" % id(obj2) ) | |
print("##########") | |
obj1.add(200) | |
print(" obj1 id = %s" % id(obj1) ) | |
print("##########") | |
print obj1.a | |
print obj2.a | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
実行結果はこんな感じ。
$ python sample1_newhook6.py
@@ 076 : func - ['obj1 = Foo(100)\n']
bac local variables {'Monitoring': <class 'main.Monitoring'>, 'builtins': <module 'builtin' (built-in)>, 'file': 'sample1_newhook6.py', 'package': None, 'name': 'main', 'Foo': <class 'main.Foo'>, 'doc': ' \xe9\x9d..... 中略 '}
called new:
>>>> instance id = 4502289376
@@ 067 : func init - [' self.a = x\n']
bac local variables {'x': 100, 'self': {}}
called setattr: id = 4502289376 (a, 100 = <type 'int'>)
obj1 id = 4502289376
@@ 078 : func - ['obj2 = Foo(200)\n']
bac local variables {'obj1': {'a': 100}, 'Monitoring': <class 'main.Monitoring'>, 'builtins': <module 'builtin' (built-in)>, 'file': 'sample1_newhook6.py', 'package': None, 'name': 'main', 'Foo': <class 'main.Foo'>, 'doc': ' \xe9\x9d....中略 '}
called new:
>>>> instance id = 4502289672
@@ 067 : func init - [' self.a = x\n']
bac local variables {'x': 200, 'self': {}}
called setattr: id = 4502289672 (a, 200 = <type 'int'>)
obj2 id = 4502289672
@@ 081 : func - ['obj1.add(200)\n']
bac local variables {'obj1': {'a': 100}, 'obj2': {'a': 200}, 'Monitoring': <class 'main.Monitoring'>, 'builtins': <module 'builtin' (built-in)>, 'file': 'sample1_newhook6.py', 'package': None, 'name': 'main', 'Foo': <class 'main.Foo'>, 'doc': ' \xe9\x9d....中略 '}
called getattribute: id = 4502289376 (add AS function)
@@ 070 : func add - [' self.a += x\n']
bac local variables {'x': 200, 'self': {'a': 100}}
called getattr: id = 4502289376 (a, 100 = <type 'int'>)
@@ 070 : func add - [' self.a += x\n']
bac local variables {'x': 200, 'self': {'a': 100}}
called setattr: id = 4502289376 (a, 300 = <type 'int'>)
obj1 id = 4502289376
@@ 084 : func - ['print obj1.a\n']
bac local variables {'obj1': {'a': 300}, 'obj2': {'a': 200}, 'Monitoring': <class 'main.Monitoring'>, 'builtins': <module 'builtin' (built-in)>, 'file': 'sample1_newhook6.py', 'package': None, 'name': 'main', 'Foo': <class 'main.Foo'>, 'doc': ' \xe9\x9d.....中略 '}
called getattr: id = 4502289376 (a, 300 = <type 'int'>)
300
@@ 085 : func - ['print obj2.a\n']
bac local variables {'obj1': {'a': 300}, 'obj2': {'a': 200}, 'Monitoring': <class 'main.Monitoring'>, 'builtins': <module 'builtin' (built-in)>, 'file': 'sample1_newhook6.py', 'package': None, 'name': 'main', 'Foo': <class 'main.Foo'>, 'doc': ' \xe9\x9d\x9e.....中略 '}
called getattr: id = 4502289672 (a, 200 = <type 'int'>)
200
$