Steven D'Aprano wrote: > Suppose I have a function f() which I know has been decorated, but I don't > have access to the original undecorated function any longer: > > def reverse(func): > def f(*args): > args = list(args) > args.reverse() > return func(*args) > return f > > def say(*args): > print args > > rsay = reverse(say) > del say > > > Is there any way to peek inside the decorated function rsay() to get > access to the undecorated function say()? > > If I look at the code object I can see a reference to the original: > >>>> rsay.func_code.co_names > ('list', 'args', 'reverse', 'func') > > and if I disassemble the code object I can see it being dereferenced: > >>>> dis.dis(rsay.func_code) > [snip for brevity] > 5 22 LOAD_DEREF 0 (func) > 25 LOAD_FAST 0 (args) > 28 CALL_FUNCTION_VAR 0 > 31 RETURN_VALUE > > but if I look at the closure object, nothing seems useful: > >>>> dir(rsay.func_closure[0]) > ['__class__', '__cmp__', '__delattr__', '__doc__', > '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', > '__reduce_ex__', '__repr__', '__setattr__', '__str__'] > > > and I can't find any other attributes which refers back to the undecorated > original function. > >
Following Terry's lead it turns out that cell contents become easily accessible in python 2.5: $ cat cellcontents.py """ >>> def reverse(func): ... def f(*args): ... args = list(args) ... args.reverse() ... return func(*args) ... return f ... >>> def say(*args): ... print args ... >>> rsay = reverse(say) >>> del say >>> c = rsay.func_closure[0] >>> "cell_contents" in dir(c) True >>> c.cell_contents(1,2,3) (1, 2, 3) >>> """ import doctest doctest.testmod() $ python2.6 cellcontents.py $ python2.5 cellcontents.py $ python2.4 cellcontents.py ********************************************************************** File "cellcontents.py", line 15, in __main__ Failed example: "cell_contents" in dir(c) Expected: True Got: False ********************************************************************** File "cellcontents.py", line 17, in __main__ Failed example: c.cell_contents(1,2,3) Exception raised: Traceback (most recent call last): File "doctest.py", line 1248, in __run compileflags, 1) in test.globs File "<doctest __main__[6]>", line 1, in ? c.cell_contents(1,2,3) AttributeError: 'cell' object has no attribute 'cell_contents' ********************************************************************** 1 items had failures: 2 of 7 in __main__ ***Test Failed*** 2 failures. Peter -- http://mail.python.org/mailman/listinfo/python-list