Messing up with classes and their namespace

Scott David Daniels Scott.Daniels at Acm.Org
Fri Jun 5 12:47:44 EDT 2009


Jean-Michel Pichavant wrote:
> Hello world,
> 
> I had recently a very nasty bug in my python application. The context is 
> quite complex, but in the end the problem can be resume as follow:
> 
> 2 files in the same directory :
> 
> lib.py:
>  >import foo
>  >foo.Foo.BOOM='lib'
> 
> foo.py:
>  >class Foo:
>  >    BOOM = 'Foooo'
>  >
>  >if __name__=='__main__':
>  >    import lib # I'm expecting BOOM to be set to 'lib'
>  >    print Foo.BOOM
> 
> I was expecting 'lib' as output, but I got 'Fooo'. I don't really 
> understand what python mechanism I'm messing with but I have the feeling 
> I've misunderstood a very basic concept about class, namespace or 
> whatever import notion.
>

> I guess there is 2 different objects for the same class Foo. How I do I 
> make both Foo objects the same object ?

OK, here is one solution (from which you may infer the problem):

lib.py:
     import __main__
     __main__.Foo.BOOM = 'lib'

foo.py:
     class Foo:
         BOOM = 'Foooo'

     if __name__ == '__main__':
         import lib # I'm expecting BOOM to be set to 'lib'
         print(Foo.BOOM)

Here is another solution:

lib.py:
     import foo
     foo.Foo.BOOM = 'lib'

foo.py:
     class Foo:
         BOOM = 'Foooo'

     if __name__ == '__main__':
         import sys
         sys.modules['foo'] = sys.modules['__main__']
         import lib # I'm expecting BOOM to be set to 'lib'
         print(Foo.BOOM)

Here is a demo of what is actually going wrong:

foo.py:
     class Foo:
         inside = __name__

     import foo

     if __name__ == '__main__':
         print(Foo is foo.Foo)
         print(Foo.inside, foo.Foo.inside)

And here is a fix
foo.py:
     if __name__ == '__main__':
         import sys
         sys.modules['foo'] = sys.modules['__main__']

     class Foo:
         inside = __name__

     import foo

     if __name__ == '__main__':
         print(Foo is foo.Foo)
         print(Foo.inside, foo.Foo.inside)


--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list