Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 1st, 2012  |  syntax: None  |  size: 1.58 KB  |  hits: 15  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. Python: Is there a way to get a local function variable from within a decorator that wraps it?
  2. import sys
  3.  
  4. class persistent_locals(object):
  5.     def __init__(self, func):
  6.         self._locals = {}
  7.         self.func = func
  8.  
  9.     def __call__(self, *args, **kwargs):
  10.         def tracer(frame, event, arg):
  11.             if event=='return':
  12.                 self._locals = frame.f_locals.copy()
  13.  
  14.         # tracer is activated on next call, return or exception
  15.         sys.setprofile(tracer)
  16.         try:
  17.             # trace the function call
  18.             res = self.func(*args, **kwargs)
  19.         finally:
  20.             # disable tracer and replace with old one
  21.             sys.setprofile(None)
  22.         return res
  23.  
  24.     def clear_locals(self):
  25.         self._locals = {}
  26.  
  27.     @property
  28.     def locals(self):
  29.         return self._locals
  30.  
  31. @persistent_locals
  32. def func():
  33.     local1 = 1
  34.     local2 = 2
  35.  
  36. func()
  37. print func.locals
  38.        
  39. def deco(func):
  40.     class Wrapper(object):
  41.         def __init__(self):
  42.             self.foo = None
  43.         def __call__(self, *args):
  44.             print 'old foo:', self.foo
  45.             result = func(*args)
  46.             print 'new foo:', self.foo
  47.             return result
  48.     return Wrapper()
  49.  
  50. @deco
  51. def my_func(new_foo):
  52.     my_func.foo = new_foo
  53.        
  54. >>> my_func('test')
  55. old foo: None
  56. new foo: test
  57. >>> my_func.foo
  58. 'test'
  59. >>> my_func(42)
  60. old foo: test
  61. new foo: 42
  62. >>> my_func.foo
  63. 42
  64.        
  65. def foo(x):
  66.     y = x + 27
  67.     return y
  68.        
  69. def myDecorator(f):
  70.   def wrapper(*args, **kwargs):
  71.     print('Arguments to this function %r / %r' % (args, kwargs))
  72.     return f(*args, **kwargs)
  73.   return wrapper