module variable scope

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Stefan Quandt

    module variable scope

    I want to set a modules global variable from outside like this:

    <begin a.py>
    v = None

    def setv( x ): v = x
    def getv(): return v
    <end a.py>

    <begin b.py>
    from a import v, setv, getv

    print v
    setv( 'hello' )
    print print getv()
    <end b.py>


    Running b.py gives:
    None
    None

    I expected variable v to be changed by calling setv() but it is not.
    Who can explain this?

    Thanks
    Stefan
  • Alex Martelli

    #2
    don't use 'from' (was Re: module variable scope)

    Stefan Quandt wrote:
    ...[color=blue]
    > <begin b.py>
    > from a import v, setv, getv[/color]

    The from statement takes a "snapshot" at that instant of time of
    the values currently bound to those names in the other module,
    binding each value to the same name in the current module.

    That's all. It establishes no magical "persistent linkage
    between names in different modules" -- there exists no concept
    of such magical persistent linkage in Python.

    Any rebinding of those or other names in the other module in
    the future will be totally irrelevant to the binding of said
    names in the current module.

    [color=blue]
    > I expected variable v to be changed by calling setv() but it is not.
    > Who can explain this?[/color]

    Who can explain your expectations, I dunno. I hope the
    explanation of the behavior was clear.

    My often-repeated recommendation is: forget the from statement's
    very existence. Use

    import b

    and refer to b.v -- NOT to bare v -- and THEN everything will work
    according to expectations.

    The 'from' statement is occasionally a handy shortcut if you
    know what you're doing, but it doesn't work well when you're
    not sure what you're doing, nor when any name rebinding or
    module reloading may be involved. That's three strikes
    against it, which means _it's out_:-).

    The 'import' statement has basically no counter-indications.
    If a module's name is long so it gets weary writing
    theothermodule. v all the time, use the 'as' clause of import:

    import theothermodule as t

    and happily refer to t.v -- just 2 characters longer than
    barename v, AND with other advantages (immediate clarity of
    where the name comes from) as well as avoiding surprises.


    Alex

    Comment

    • Dennis Lee Bieber

      #3
      Re: module variable scope

      Stefan Quandt fed this fish to the penguins on Tuesday 28 October 2003
      05:37 am:
      [color=blue]
      >
      >
      > I want to set a modules global variable from outside like this:
      >
      > <begin a.py>
      > v = None
      >
      > def setv( x ): v = x[/color]

      Problem #1... this /v/ is LOCAL to setv(). You need

      def setv(x):
      global v
      v = x
      [color=blue]
      > def getv(): return v
      > <end a.py>
      >
      > <begin b.py>
      > from a import v, setv, getv
      >[/color]
      Problem #2... from <> import <> is /evil/

      What you have done is make new /local/ labels for the objects named.

      Fixing problem #1 will result in the label "a.v" being moved to the
      object containing "x". NOTE: the LABEL moved... "b.v" is not moved,
      only "a.v".

      --[color=blue]
      > =============== =============== =============== =============== == <
      > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
      > wulfraed@dm.net | Bestiaria Support Staff <
      > =============== =============== =============== =============== == <
      > Bestiaria Home Page: http://www.beastie.dm.net/ <
      > Home Page: http://www.dm.net/~wulfraed/ <[/color]

      Comment

      • Stefan Quandt

        #4
        Re: don't use 'from' (was Re: module variable scope)

        Alex Martelli <aleax@aleax.it > wrote in message news:<8tunb.366 820$R32.1209572 7@news2.tin.it> ...[color=blue]
        > Stefan Quandt wrote:
        > ...[color=green]
        > > <begin b.py>
        > > from a import v, setv, getv[/color]
        >
        > The from statement takes a "snapshot" at that instant of time of
        > the values currently bound to those names in the other module,
        > binding each value to the same name in the current module.
        >
        > That's all. It establishes no magical "persistent linkage
        > between names in different modules" -- there exists no concept
        > of such magical persistent linkage in Python.
        >
        > Any rebinding of those or other names in the other module in
        > the future will be totally irrelevant to the binding of said
        > names in the current module.
        >[/color]
        Oh, I thought that 'from' is a means to explicitly import selected
        symbols from a module instead of importing the whole.
        I never was aware of the different semantics of using 'from' in
        imports.
        In this case python does not work like one would intuitively expect.

        Of course one could find a hint in the reference manual 6.12:
        The from form does not bind the module name: it goes through the list
        of identifiers, looks each one of them up in the module found in step
        (1), and binds the name in the local namespace to the object thus
        found.

        Thanks
        Stefan

        Comment

        Working...