Logging method calls
از PyLearn.com، دانشنامهٔ آزاد.
| کتاب پایتون • ماژول ها و ابزار وابسته • نمونه پروژه و برنامه • پرسش و پاسخ |
در مثال زیر با استفاده از مبحث meta class عملیات log کردن یک تابع یا توابع کلاس انجام می گیرد !
می توان با الهام از این کد و روش هایی شبیه به آن و با استفاده از مبحث meta class برنامه هایی را نوشت که قبل و بعد از اجرای تابع یا توابع کلاس خاص اجرا شده و دستورات و وظایف محوله را انجام دهند .
در این مثال تابع method_ به همراه هر تابع در هنگام اجرا آن و نیز خاتمه آن اجرا می گردد و روند کار تابع را در فایل خارجی ثبت می کند !
این روش برای خطایابی و مشاهده نحوه کار توابع و مخصوصا توابه بازگشتی بسیار مفید می باشد .
import re
log = open('log','w')
indent = 0
indStr = ' '
def logmethod(methodname):
def _method(self,*argl,**argd):
global indent
#parse the arguments and create a string representation
args = []
for item in argl:
args.append('%s' % str(item))
for key,item in argd.items():
args.append('%s=%s' % (key,str(item)))
argstr = ','.join(args)
print >> log,"%s%s.%s(%s) " % (indStr*indent,str(self),methodname,argstr)
indent += 1
# do the actual method call
returnval = getattr(self,'_H_%s' % methodname)(*argl,**argd)
indent -= 1
print >> log,'%s:'% (indStr*indent), str(returnval)
return returnval
return _method
class LogTheMethods(type):
def __new__(cls,classname,bases,classdict):
logmatch = re.compile(classdict.get('logMatch','.*'))
for attr,item in classdict.items():
if callable(item) and logmatch.match(attr):
classdict['_H_%s'%attr] = item # rebind the method
classdict[attr] = logmethod(attr) # replace method by wrapper
return type.__new__(cls,classname,bases,classdict)
class Test(object):
__metaclass__ = LogTheMethods
logMatch = '.*'
def __init__(self):
self.a = 10
def meth1(self):pass
def add(self,a,b):return a+b
def fac(self,val): # faculty calculation
if val == 1:
return 1
else:
return val * self.fac(val-1)
if __name__ == '__main__':
l = Test()
l.meth1()
print l.add(1,2)
print l.fac(10)
نمونه log فایل :
<__main__.Test object at 0xb7bb276c>.__init__()
: None
<__main__.Test object at 0xb7bb276c>.meth1()
: None
<__main__.Test object at 0xb7bb276c>.add(1,2)
: 3
<__main__.Test object at 0xb7bb276c>.fac(10)
<__main__.Test object at 0xb7bb276c>.fac(9)
<__main__.Test object at 0xb7bb276c>.fac(8)
<__main__.Test object at 0xb7bb276c>.fac(7)
<__main__.Test object at 0xb7bb276c>.fac(6)
<__main__.Test object at 0xb7bb276c>.fac(5)
<__main__.Test object at 0xb7bb276c>.fac(4)
<__main__.Test object at 0xb7bb276c>.fac(3)
<__main__.Test object at 0xb7bb276c>.fac(2)
<__main__.Test object at 0xb7bb276c>.fac(1)
: 1
: 2
: 6
: 24
: 120
: 720
: 5040
: 40320
: 362880
: 3628800
در فایل log نام هر تابع ، مفدار ارسالی ، مقدار برگشتی ، آدرس حافظه و ... بصورت بسیار واضحی نمایش داده شده است

