Overhead of (was Reasoning behind) nested scope

Nigel Rowe rho at see.signature.invalid
Tue Aug 3 23:02:21 EDT 2004


Peter Otten wrote:

> Andy Baker wrote:
> 
>> (On a side note is there any way to call a nested function from outside
>> the parent? I was kind of expecting nested functions to be addressable
>> through dot notation like methods are but I can see why that wouldn't be
>> quite right. This might be a better question for the tutor list...)
> 
> When you are nesting functions, you don't get one function sitting inside
> another function. Instead, the function creation code of the "inner"
> function is executed every time to the effect that you get a new inner
> function every time you call the outer one:
> 
>>>> def make():
> ...     def f(): return "shoobidoo"
> ...     return f
> ...
>>>> f1 = make()
>>>> f2 = make()
>>>> f1(), f2()
> ('shoobidoo', 'shoobidoo')
>>>> f1 is f2
> False
> 
> You wouldn't do that in cases like the above, when you get nothing in
> return for the extra overhead, but somtimes nesting is useful - because of
> the change in the scoping rules you now get readonly-closures:
> 
>>>> def make(s):
> ...     def f(): return s
> ...     return f
> ...
>>>> f1 = make("now")
>>>> f2 = make("what")
>>>> f1(), f2()
> ('now', 'what')
> 
> Peter

What work is actually done when the 
        'nested function creation code of the "inner" function'
is executed?

Given a quick test:-
<code>
def outer():
    def inner():
        pass
    return inner

b1 = outer()
b2 = outer()

attrs=[a for a in dir(b1) if not a.startswith('_')]
for a, a1, a2 in zip(attrs,
                     [getattr(b1,a) for a in attrs],
                     [getattr(b2,a) for a in attrs]):
    print a, a1 is a2

</code>
<result>
func_closure True
func_code True
func_defaults True
func_dict True
func_doc True
func_globals True
func_name True
</result>

it appears that all the components of the inner function are the same, which
just leaves the binding of the code object to 'inner'.

Am I missing something, or is the overhead no worse than, say, foo=self.foo,
where self.foo is a method?


-- 
        Nigel Rowe
        A pox upon the spammers that make me write my address like..
                rho (snail) swiftdsl (stop) com (stop) au



More information about the Python-list mailing list