Function creation (what happened?)

Duncan Booth duncan.booth at invalid.invalid
Fri May 9 08:40:12 EDT 2008


Viktor <alefnula at gmail.com> wrote:

> Can somebody give me an explanation what happened here (or point me to
> some docs)?
> 
> Code:
> 
> HMMM = None
> 
> def w(fn):
>     print 'fn:', id(fn)
>     HMMM = fn
>     print 'HMMM:', id(HMMM)
>     def wrapper(*v, **kw):
>         fn(*v, **kw)
>     wrapper.i = fn
>     print 'wrapper:', id(wrapper)
>     return wrapper
> 
> class A:
>     @w
>     def __init__(self): pass
> 
> print 'A.__init__:', id(A.__init__)
> print 'A.__init__.i:', id(A.__init__.i)
> print 'HMMM:', id(HMMM)
> 
> 
> 
> Output:
> 
> fn: 10404208
> HMMM: 10404208
> wrapper: 10404272
> A.__init__: 10376136
> A.__init__.i: 10404208
> HMMM: 505264624
> 
> 
> 
> Why did HMMM changed his id?!

It didn't: global HMMM refers to None both before and after executing 
the rest of your code. The other HMMM is local to a particular 
invocation of w. Try the same steps interactively (and try printing the 
values not just the ids) and it may be more obvious:

>>> HMMM = None
>>> print 'HMMM:', id(HMMM)
HMMM: 505264624
>>> def w(fn):
    print 'fn:', id(fn)
    HMMM = fn
    print 'HMMM:', id(HMMM)
    def wrapper(*v, **kw):
        fn(*v, **kw)
    wrapper.i = fn
    print 'wrapper:', id(wrapper)
    return wrapper

>>> class A:
    @w
    def __init__(self): pass

    
fn: 18299952
HMMM: 18299952
wrapper: 18300016
>>> print 'HMMM:', id(HMMM), HMMM
HMMM: 505264624 None
>>> 



More information about the Python-list mailing list