Messing up with classes and their namespace

Discussion in 'Python' started by Jean-Michel Pichavant, Jun 5, 2009.

  1. 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.

    This is how I made it work:
    >if __name__=='__main__':
    > from lib import Foo # make sure Foo comes from lib
    > print Foo.BOOM



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

    Jean-Michel
    Jean-Michel Pichavant, Jun 5, 2009
    #1
    1. Advertising

  2. Scott David Daniels wrote:
    > 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
    >


    Thanks for the explanation. I'll have to give it a second thought, I'm
    still missing something but I'll figure it out.

    Jean-Michel
    Jean-Michel Pichavant, Jun 5, 2009
    #2
    1. Advertising

  3. Jean-Michel Pichavant

    Terry Reedy Guest

    Jean-Michel Pichavant wrote:

    > Thanks for the explanation. I'll have to give it a second thought, I'm
    > still missing something but I'll figure it out.


    Perhaps it is this:
    1. When you run foo.py as a script, the interpreter creates module
    '__main__' by executing the code in foo.py.
    2. When that code does 'import lib', the interpreter looks for an
    existing module named 'lib', does not find it, and creates module 'lib'
    by executing the code in lib.py.
    3. When that code does 'import foo', the interpreter looks for an
    existing module named 'foo', does not find it, and creates module 'foo'
    by executing (again) the code in foo.py.

    Module 'foo' is slightly different from module '__main__', created from
    the same code, because of the section conditioned by 'if __name__ ==
    '__main__', that being the purpose of that incantation. But each of the
    two modules have their own class Foo. You sort of guessed this ...

    > I guess there is 2 different objects for the same class Foo.


    They are the same in content, but not in identify, until you change one
    of then.

    > How I do I make both Foo objects the same object ?


    As Scott hinted, by not making two of them, and you do that by not
    making two modules from the same file.

    Terry Jan Reedy
    Terry Reedy, Jun 5, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. CJ
    Replies:
    6
    Views:
    325
  2. Replies:
    6
    Views:
    365
  3. Robert Hicks

    Re: Spaces and tabs messing up code

    Robert Hicks, Jan 9, 2008, in forum: Python
    Replies:
    1
    Views:
    333
    Ben Finney
    Jan 9, 2008
  4. Markus Fischer
    Replies:
    5
    Views:
    161
    Gary Wright
    Jun 2, 2009
  5. Dave Ardrey

    Messing with UID's and GID's

    Dave Ardrey, Jun 30, 2003, in forum: Perl Misc
    Replies:
    1
    Views:
    127
    Greg Bacon
    Jun 30, 2003
Loading...

Share This Page