Prev: Capture the request/response log for local web server through python.
Next: python local web server
From: John Nagle on 14 Jun 2010 23:46 I'm doing something with CPython introspection, and I'm trying to determine whether a function is a closure. Consider def foo(x) : global fbar def bar(y) : pass fbar = bar # export closure foo(0) We now have "fbar" as a reference to a closure. "inspect" can tell us some things about foo and fbar: >>> inspect.getargspec(foo) ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None) >>> inspect.getargspec(fbar) ArgSpec(args=['y'], varargs=None, keywords=None, defaults=None) No difference there. >>> fbar.func_globals {'fbar': <function bar at 0x021FD470>, '__builtins__': <module '__builtin__' (built-in)>, 'inspect': <module 'inspect' from 'C:\python26\lib\inspect.pyc'>, 'm': [('__call__', <method-wrapper '__call__' of function object at 0x021FD470>), ('__class__', <type 'function'>), ('__closure__', None), ('__code__', <code object bar at 021F1C38, file "<stdin>", line 3>), ('__defaults__', None), ('__delattr__', <method-wrapper '__delattr__' of function object at 0x021FD470>), ('__dict__', {}), ('__doc__', None), ('__format__', <built-in method __format__ of function object at 0x021FD470>), ('__get__', <method-wrapper '__get__' of function object at 0x021FD470>), ('__getattribute__', <method-wrapper '__getattribute__' of function object at 0x021FD470>), ('__globals__', {...}), ('__hash__', <method-wrapper '__hash__' of function object at 0x021FD470>), ('__init__', <method-wrapper '__init__' of function object at 0x021FD470>), ('__module__', '__main__'), ('__name__', 'bar'), ('__new__', <built-in method __new__ of type object at 0x1E1FACF0>), ('__reduce__', <built-in method __reduce__ of function object at 0x021FD470>), ('__reduce_ex__', <built-in method __reduce_ex__ of function object at 0x021FD470>), ('__repr__', <method-wrapper '__repr__' of function object at 0x021FD470>), ('__setattr__', <method-wrapper '__setattr__' of function object at 0x021FD470>), ('__sizeof__', <built-in method __sizeof__ of function object at 0x021FD470>), ('__str__', <method-wrapper '__str__' of function object at 0x021FD470>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x1E1FACF0>), ('func_closure', None), ('func_code', <code object bar at 021F1C38, file "<stdin>", line 3>), ('func_defaults', None), ('func_dict', {}), ('func_doc', None), ('func_globals', {...}), ('func_name', 'bar')], '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x02223C70>, '__doc__': None} >>> No indication there that "fbar" is a closure inside "foo". There are "__closure__" and "__func_closure__" entries in there, but they are both None. A non-closure function has the same entries. So how can I detect a closure? John Nagle
From: Steven D'Aprano on 15 Jun 2010 00:33 On Mon, 14 Jun 2010 20:46:28 -0700, John Nagle wrote: > So how can I detect a closure? I *think* you do it through the co_flags attribute of the code object. This is in Python 2.5: >>> def f(x): .... def g(): .... return x .... return g .... >>> >>> closure = f(42) >>> closure() 42 >>> closure.func_code.co_flags 19 >>> f.func_code.co_flags 3 although this doesn't seem to be documented, at least not here: http://docs.python.org/reference/datamodel.html -- Steven
From: Ian Kelly on 15 Jun 2010 00:39 On Mon, Jun 14, 2010 at 9:46 PM, John Nagle <nagle(a)animats.com> wrote: > No indication there that "fbar" is a closure inside "foo". There > are "__closure__" and "__func_closure__" entries in there, but > they are both None. A non-closure function has the same entries. > > So how can I detect a closure? Maybe because it has no non-local references, so it's not really a closure? >>> def foo(x): .... global fbar .... def bar(y): .... pass .... fbar = bar .... >>> foo(0) >>> fbar.func_closure >>> >>> def foo(x): .... global fbar .... def bar(y): .... x .... fbar = bar .... >>> foo(0) >>> fbar.func_closure (<cell at 0x7ffb7dbd8210: int object at 0xa9f2b0>,) Cheers, Ian
From: John Nagle on 15 Jun 2010 01:58 On 6/14/2010 9:33 PM, Steven D'Aprano wrote: > On Mon, 14 Jun 2010 20:46:28 -0700, John Nagle wrote: > >> So how can I detect a closure? > > I *think* you do it through the co_flags attribute of the code object. > This is in Python 2.5: > > although this doesn't seem to be documented, at least not here: > > http://docs.python.org/reference/datamodel.html Got it. Check f.func_closure for a non-null value. For a closure, the value will be a Cell object. The value of "func_closure" in f.func_globals is None, but that's the wrong place to look, apparently. John Nagle
|
Pages: 1 Prev: Capture the request/response log for local web server through python. Next: python local web server |