Can someone explain this behavior to me?

Discussion in 'Python' started by Jesse Aldridge, Feb 26, 2009.

  1. I have one module called foo.py
    ---------------------
    class Foo:
    foo = None

    def get_foo():
    return Foo.foo

    if __name__ == "__main__":
    import bar
    Foo.foo = "foo"
    bar.go()
    ---------------------
    And another one called bar.py
    ---------------------
    import foo

    def go():
    assert foo.get_foo() == "foo"
    ----------------------
    When I run foo.py, the assertion in bar.py fails. Why?
     
    Jesse Aldridge, Feb 26, 2009
    #1
    1. Advertising

  2. Jesse Aldridge

    Chris Rebert Guest

    On Thu, Feb 26, 2009 at 1:48 PM, Jesse Aldridge <> wrote:
    > I have one module called foo.py
    > ---------------------
    > class Foo:
    >    foo = None
    >
    > def get_foo():
    >    return Foo.foo
    >
    > if __name__ == "__main__":
    >    import bar
    >    Foo.foo = "foo"
    >    bar.go()
    > ---------------------
    > And another one called bar.py
    > ---------------------
    > import foo
    >
    > def go():
    >    assert foo.get_foo() == "foo"
    > ----------------------
    > When I run foo.py, the assertion in bar.py fails.  Why?


    Not sure, but circular imports are *evil* anyway, so I'd suggest you
    just rewrite the code to avoid doing any circular imports in the first
    place.

    Cheers,
    Chris

    --
    Follow the path of the Iguana...
    http://rebertia.com
     
    Chris Rebert, Feb 26, 2009
    #2
    1. Advertising

  3. Jesse Aldridge

    John Machin Guest

    On Feb 27, 8:48 am, Jesse Aldridge <> wrote:
    > I have one module called foo.py
    > ---------------------
    > class Foo:
    >     foo = None
    >
    > def get_foo():
    >     return Foo.foo
    >
    > if __name__ == "__main__":
    >     import bar
    >     Foo.foo = "foo"
    >     bar.go()
    > ---------------------
    > And another one called bar.py
    > ---------------------
    > import foo
    >
    > def go():
    >     assert foo.get_foo() == "foo"
    > ----------------------
    > When I run foo.py, the assertion in bar.py fails.  Why?


    AFAICT from that convoluted mess, because there are two rabbit holes,
    __main__.Foo.foo and foo.Foo.foo, and you poked "foo" down the wrong
    one. In any case the other one is not the right one -- as you have
    already been advised, circular imports are evil.
     
    John Machin, Feb 26, 2009
    #3
  4. On Thu, 2009-02-26 at 13:48 -0800, Jesse Aldridge wrote:
    > I have one module called foo.py
    > ---------------------
    > class Foo:
    > foo = None
    >
    > def get_foo():
    > return Foo.foo
    >
    > if __name__ == "__main__":
    > import bar
    > Foo.foo = "foo"
    > bar.go()
    > ---------------------
    > And another one called bar.py
    > ---------------------
    > import foo
    >
    > def go():
    > assert foo.get_foo() == "foo"
    > ----------------------
    > When I run foo.py, the assertion in bar.py fails. Why?


    AFAICT you have 2 different "foo" modules here. The first foo is when
    foo.py is called as a script, but it's not called "foo" it's called
    "__main__" because it's called as a script. When "bar" is imported, it
    imports "foo", but this is different. Technically this is the first time
    you are *importing* foo. It's actually loaded a second time with the
    name "foo".

    A more simplified version of it is this:

    $ cat foo.py
    cat = 6
    import bar
    print '%s: %s.cat = %s' % (__file__, __name__, cat)

    $ cat bar.py
    import foo
    foo.cat = 7
    print '%s: %s.cat = %s' % (__file__, foo.__name__, foo.cat)

    $ python foo.py
    /home/marduk/test/foo.py: foo.cat = 6
    /home/marduk/test/bar.py: foo.cat = 7
    foo.py: __main__.cat = 6


    OTOH:
    $ python -c "import foo"
    bar.py: foo.cat = 7
    foo.py: foo.cat = 7

    But, as others have said, this is confusing and should be avoided.

    -a
     
    Albert Hopkins, Feb 26, 2009
    #4
  5. Jesse Aldridge

    Steve Holden Guest

    Jesse Aldridge wrote:
    > I have one module called foo.py
    > ---------------------
    > class Foo:
    > foo = None
    >
    > def get_foo():
    > return Foo.foo
    >
    > if __name__ == "__main__":
    > import bar
    > Foo.foo = "foo"
    > bar.go()
    > ---------------------
    > And another one called bar.py
    > ---------------------
    > import foo
    >
    > def go():
    > assert foo.get_foo() == "foo"
    > ----------------------
    > When I run foo.py, the assertion in bar.py fails. Why?


    There are actually two get_foo()s, since foo.py is run (giving it the
    name "__main__") and imported (giving it the name "foo"). You will
    probably find that __main__.get_foo() == "foo".

    regards
    Steve

    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    Holden Web LLC http://www.holdenweb.com/
     
    Steve Holden, Feb 27, 2009
    #5
  6. Ah, I get it.
    Thanks for clearing that up, guys.
     
    Jesse Aldridge, Feb 27, 2009
    #6
    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. Replies:
    1
    Views:
    390
    brucie
    Dec 3, 2003
  2. Michael Kent
    Replies:
    4
    Views:
    425
    David MacQuigg
    Jun 15, 2004
  3. Tim Peters
    Replies:
    2
    Views:
    319
    Mike C. Fletcher
    Jun 14, 2004
  4. Mike Kent
    Replies:
    9
    Views:
    344
    Mike Kent
    Jan 24, 2008
  5. broli

    Can someone explain this behavior ?

    broli, Mar 15, 2008, in forum: C Programming
    Replies:
    5
    Views:
    356
    Ben Bacarisse
    Mar 16, 2008
Loading...

Share This Page