Messing up with classes and their namespace

  • Thread starter Jean-Michel Pichavant
  • Start date
J

Jean-Michel Pichavant

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
 
J

Jean-Michel Pichavant

Scott said:
Jean-Michel Pichavant said:
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:

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
(e-mail address removed)

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
 
T

Terry Reedy

Jean-Michel Pichavant said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top