1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# -*- coding: utf-8 -*- from __future__ import print_function import time import sys import cPickle from time import strftime import inspect import traceback """ Decorator Resources http://www.ellipsix.net/blog/2010/8/more-python-voodoo-optional-argument-decorators.html http://stackoverflow.com/questions/3931627/how-to-build-a-python-decorator-with-optional-parameters/3931903#3931903 http://typeandflow.blogspot.com/2011/06/python-decorator-with-optional-keyword.html http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/ http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize http://wiki.python.org/moin/PythonDecoratorLibrary#Asynchronous_Call http://code.activestate.com/recipes/496879-memoize-decorator-function-with-cache-size-limit/ """ def main(): if True: pass return bb="ten" aa="wow" bigboy(bb, aa) def bigboy(tima, boo): y = "gee man" fooo(y) trace(msg="great") import datetime print(datetime.datetime.now()) for i in range(0,5): from time import sleep sleep(1) print(meo()) def fooo(x): #trace_inspect() try: print(1/0) except ZeroDivisionError as e: #print_exc_plus() print_ex() #frames = inspect.trace() #argvalues = inspect.getargvalues(frames[0][0]) #print("Argvalues: ", inspect.formatargvalues(*argvalues)) def timing_old_old(f): def wrapper(*arg): t = time.clock() try: return f(*arg) finally: print(str(env('PATH_INFO'))+"\t"+str(f.func_name)+"\t"+str((time.clock()-t)*1000)) return wrapper def decoratorFunctionWithArguments(arg1=None): def wrap(f): print ("Inside wrap(arg1:"+str(arg1)+")") def inner_wrap(*args): print ("Inside wrapped_f()") print("Decorator arguments:"+str(arg1)) res = f(*args) print (res) return res return inner_wrap return wrap def print_exc_plus(): """ Print the usual traceback information, followed by a listing of all the local variables in each frame. """ tb = sys.exc_info()[2] stack = [] while tb: f = tb.tb_frame while f: stack.append(f) f = f.f_back tb = tb.tb_next traceback.print_exc() print ("Locals by frame, innermost last") for frame in stack: if frame.f_code.co_name == "<module>": # so it does not dump globals continue print("Frame %s in %s at line %s" % (frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno)) for key, value in frame.f_locals.items(): strx = "\t%20s = " % key #We have to be careful not to cause a new error in our error #printer! Calling str() on an unknown object could cause an #error we don't want. try: strx +=str( value) except: strx += "<ERROR WHILE PRINTING VALUE>, " print(strx) #def print_ex_local(): # import tracebackturbo as traceback # print(traceback.format_exc(with_vars=True)) def print_ex(): cla, exc, exc_traceback= sys.exc_info() exc_args = exc.__dict__["args"] if "args" in exc.__dict__ else "<no args>" ex_title = cla.__name__+"exc:"+str(exc)+" - args:"+str(exc_args) msgs = [ex_title] except_location ="" tb = traceback.extract_tb(exc_traceback) for filename,lineno,fn,exec_line in tb: # ('gdecorators.py', 60, 'newfoo', 'print(1/0)') except_location += filename+":"+str(lineno)+" - "+str(fn)+" - "+exec_line stacks = inspect.stack() for i in range(0, len(stacks)): stack = stacks[i] (first_val, filename,linenumber,module,fn,_) = stack linenumber = stacks[i+1][2] if i<len(stacks)-1 else "?" # overwrite line number params = inspect.getargvalues(first_val) msgs.append( filename+":"+str(linenumber)+" - "+str(module)+str( inspect.formatargvalues(*params))) msgs.insert(2, except_location) time = strftime("%Y-%m-%d %H:%M:%S") print(time +" - "+("\n".join(msgs))) def print_except_alternative(maxTBlevel=5): cla, exc, trbk = sys.exc_info() excName = cla.__name__ try: excArgs = exc.__dict__["args"] except KeyError: excArgs = "<no args>" excTb = traceback.format_tb(trbk, maxTBlevel) return (excName, excArgs, excTb) """ Tips: http://stackoverflow.com/questions/6061744/how-to-get-value-of-arguments-in-functions-at-stack http://stackoverflow.com/questions/1650713/get-last-functions-call-arguments-from-traceback http://bip.weizmann.ac.il/course/python/PyMOTW/PyMOTW/docs/traceback/index.html """ import inspect def trace_inspect(): stacks = inspect.stack() msgs =[] for i in range(0, len(stacks)): stack = stacks[i] (first_val, filename,linenumber,module,fn,_) = stack linenumber = stacks[i+1][2] if i<len(stacks)-1 else "?" # overwrite line number params = inspect.getargvalues(first_val) msgs.append( filename+":"+str(linenumber)+" - "+str(module)+str( inspect.formatargvalues(*params))) #print("\n".join(msgs)) time = strftime("%Y-%m-%d %H:%M:%S") print(time +" - "+("\n".join(msgs))) def trace(msg=None, params=True): show_stack(inspect.stack()[1], msg, params) def show_stack(stack, msg="", params=True): (first_val, filename,linenumber,module,fn,_) = stack parameters = inspect.getargvalues(first_val) msg = " - "+str(msg) if msg else "" strx = strftime("%Y-%m-%d %H:%M:%S")+" - " strx += filename+":"+str(linenumber)+msg+" - "+str(module) if params: strx += str( inspect.formatargvalues(*parameters)) print(strx) def nprint(element): from pprint import pprint import sys, StringIO out = StringIO.StringIO() pprint(element,out) return str(out.getvalue()) # http://www.siafoo.net/article/68 # being nice to subsequent decorator calls or chains, otherwise losing the name of the function def timing(result=True, params=True, start=False): def timing_decorator(f): def wrapper(*args, **kw): t1 = time.time() function_result = None try: function_result = f(*args, **kw) return function_result finally: t2 = time.time() from time import strftime strx = strftime("%Y-%m-%d %H:%M:%S") if params and result: if args and kw: strx +=' - % 8.f ms - %s(%r, %r) => %s' % ((t2-t1)*1000.0, f.func_name, str(args), str(kw), str(nprint(function_result))) elif args and not kw: strx +=' - % 8.f ms - %s(%r) => %s' % ((t2-t1)*1000.0, f.func_name, str(args), str(nprint(function_result))) elif not args and kw: strx +=' - % 8.f ms - %s(%r) => %s' % ((t2-t1)*1000.0, f.func_name, str(kw), str(nprint(function_result))) else: strx +=' - % 8.f ms - %s() => %s' % ((t2-t1)*1000.0, f.func_name, str(nprint(function_result))) elif params and not result: if args and kw: strx +=' - % 8.f ms - %s(%r, %r)' % ((t2-t1)*1000.0, f.func_name, str(args), str(kw)) elif args and not kw: strx +=' - % 8.f ms - %s(%r)' % ((t2-t1)*1000.0, f.func_name, str(args)) elif not args and kw: strx +=' - % 8.f ms - %s(%r)' % ((t2-t1)*1000.0, f.func_name, str(kw)) else: strx +=' - % 8.f ms - %s()' % ((t2-t1)*1000.0, f.func_name) elif not params and result: strx +=' - % 8.f ms - %s() => %s' % ((t2-t1)*1000.0, f.func_name, str(nprint(function_result))) else: strx +=' - % 8.f ms - %s()' % ((t2-t1)*1000.0, f.func_name ) if start: d = datetime.fromtimestamp(t1) strx += " start:"+d.strftime("%Y-%m-%d %H:%M:%S") print(strx) wrapper.func_name = f.func_name return wrapper return timing_decorator def memory(ttl=24*60*60*1000): # default 1 day def cache_decorator(f): cache = {} def wrapper(*args, **kw): try: #ttl= 5 * 1000 import cPickle key = f.func_name + cPickle.dumps((args, kw)) # f.func_name + str(args) res = cache.get(key) if res: created, result = res.get('created'), res.get('result') age_ms = (time.time() - created)*1000.0 if age_ms < ttl: return result result = f(*args, **kw) data = {'result': result, 'created': time.time() } cache[key] = data # might need to serialize the data here, just to be sure return result except TypeError: # uncachable -- for instance, passing a list as an argument. # Better to not cache than to blow up entirely. return f(*args, **kw) wrapper.func_name = f.func_name return wrapper return cache_decorator def memoize_limited(function, limit=None): dict = {} list = [] def memoize_wrapper(*args, **kwargs): key = cPickle.dumps((args, kwargs)) try: list.append(list.pop(list.index(key))) except ValueError: dict[key] = function(*args, **kwargs) list.append(key) if limit is not None and len(list) > limit: del dict[list.pop(0)] return dict[key] def propget(func): locals = sys._getframe(1).f_locals name = func.__name__ prop = locals.get(name) if not isinstance(prop, property): prop = property(func, doc=func.__doc__) else: doc = prop.__doc__ or func.__doc__ prop = property(func, prop.fset, prop.fdel, doc) return prop def propset(func): locals = sys._getframe(1).f_locals name = func.__name__ prop = locals.get(name) if not isinstance(prop, property): prop = property(None, func, doc=func.__doc__) else: doc = prop.__doc__ or func.__doc__ prop = property(prop.fget, func, prop.fdel, doc) return prop def propdel(func): locals = sys._getframe(1).f_locals name = func.__name__ prop = locals.get(name) if not isinstance(prop, property): prop = property(None, None, func, doc=func.__doc__) else: prop = property(prop.fget, prop.fset, func, prop.__doc__) return prop import functools def suppress_errors(func=None, log_func=None): """Automatically silence any errors that occur within a function""" def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: if log_func is not None: log_func(str(e)) return wrapper if func is None: return decorator else: return decorator(func) @memory(3*1000) @timing() def meo(): from time import sleep sleep(1) print("hi jimmy") return "done meo" if __name__ == "__main__": main() |