Re: Imported globals?

Discussion in 'Python' started by Valentina Vaneeva, Jul 27, 2007.

  1. On Jul 27, 2007, at 10:56 PM, Gary Herron wrote:

    > The variable "value" is global in module_a, and "change_value" will
    > always refer to that variable.
    >
    > However, in module_b, when you from module_a import value,
    > change_value
    > you have created two new variables global to module_b that references
    > values from the other module.
    > Now running change_value (which changes "value" in module_a has no
    > affect on the version of "value" in module_b. Your print is then
    > printing value from module_b -- the unchanged version.


    Thank you, Gary, but I still have one question. What happens in the
    second case? If I add a call to change_value() to module_a, the value
    in module_b is imported changed. Why? What exactly does the import
    statement import in my example?

    > Ideas:
    > 1 If you want module_a to manage such a global variable, you could
    > include functions for getting, and setting it, as well as your
    > function for changing it's value.
    >
    > 2. You could also dispense with use of global values -- various OOP
    > techniques could help there.


    Thanks, this part is not a problem :)


    Cheers,
    Valia
    Valentina Vaneeva, Jul 27, 2007
    #1
    1. Advertising

  2. Valentina Vaneeva

    Guest

    On Jul 27, 1:30 pm, Valentina Vaneeva <> wrote:

    > Thank you, Gary, but I still have one question. What happens in the
    > second case? If I add a call to change_value() to module_a, the value
    > in module_b is imported changed. Why? What exactly does the import
    > statement import in my example?


    Because then by the time you import the thing, that action has been
    carried out. Consider:

    from module_a import change_value
    change_value()
    from module a import value
    print value

    It's not significantly different from this:

    -----
    class NotaModule(object):
    pass

    nota = NotaModule()
    nota.a = 1

    def change_it():
    global nota # not even sure you need this
    nota.a = 2

    a = nota.a
    change_it()
    print a, nota.a
    ------

    Modules and (singleton) objects are rather similar from the outside,
    afaik.

    Also consider that this is yet another case where if value or A was a
    list and you appended to it, both prints would show the change,
    mutable objects, etc.

    --
    Tired Weaver
    , Jul 27, 2007
    #2
    1. Advertising

  3. Valentina Vaneeva

    anethema Guest

    > It seems that in the first case change_value() called in module_b.py
    > ignores the global statement. Is it so? Why? What happens in the second
    > case? I really don't get it.


    The key is that it doesn't ignore the global statement, but that
    global specifically points to the variable 'value' in module A's
    namespace. That is, even though you call change_it() from module B,
    it acts on the variable in module A, not B, even though 'value' exists
    in B.

    consider the following modules:

    module_a.py
    value = 'initial'

    def change_it():
    global value
    value = 'changed'

    def print_it():
    print "In module A:", value

    print_it()

    module_b.py
    from module_a import value, change_it, print_it as a_print_it()

    def print_it():
    print "In module B:", value

    print_it()
    change_it()
    a_print_it()
    print_it()


    $> python module_b.py
    In module A: initial
    In module B: initial
    In module A: changed
    In module B: initial

    Here we see that a) print_it() was executed in module A before the
    code in module B ran; This happens at import. b) after change_it()
    was executed, 'value' in module A was changed, while 'value' in module
    B was left alone.

    This demonstrates how the modules have separate namespaces, but also
    hinges on the fact that strings are immutable, as star.public
    mentions. 'value' in both namespaces do refer to the same object.
    What's significant is the action on the method change_it(). For
    example,

    def change_it():
    value = 'changed'

    this would do no good at all, as you may have realized, as it merely
    assigns the string 'changed' to the name/variable 'value' in the
    function namespace. If there is an assignment to a variable in a
    function (not an attribute of some other variable), such as 'a = 2',
    the interpreter assumes that the function is declaring a new
    variable. We need to explicitly declare the variable global first.
    If we don't, and try to treat it global, the above useless function
    can result, or the following

    def change_it():
    if value == 'initial':
    value = 'changed'

    which results in a UnboundLocalError, since, defaulting to using
    'value' as a local variable (since we have the assign statement `value
    = 'changed'`), and we attempt to use the local var before assigning it
    a value.

    For mutable objects, such as a list, or classes (and their
    attributes), the result would be different.

    module_a.py
    value = ['initial']

    def change_it():
    value[0] = 'initial' # don't need the 'global value', since
    we're accessing attributes
    # of 'value', not directly accessing
    value

    def print_it():
    print "In module A:", value[0]

    print_it()

    module_b.py
    from module_a import value, change_it, print_it as a_print_it

    def print_it():
    print "In module B:", value[0]

    print_it()
    change_it()
    a_print_it()
    print_it()

    $> python module_b.py
    In module A: initial
    In module B: initial
    In module A: changed
    In module B: changed


    In this case, the two module namespaces still each contain a reference
    to the same object. What we did differently is change the object
    itself, instead of the reference. If change_it() assigned to value,
    `value = ['changed']`, we would see no different behavior than in the
    first case.


    Sorry if that was overly winded. scope and namespaces are tricky (at
    least for me) to explain.
    - Jeremy
    anethema, Jul 28, 2007
    #3
  4. Thank you all, guys. I think, now I understand import behavior more :)


    Cheers,
    Valia
    Valentina Vaneeva, Jul 28, 2007
    #4
    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. James Tauber

    passing globals to imported module

    James Tauber, Aug 16, 2004, in forum: Python
    Replies:
    5
    Views:
    328
    James Tauber
    Aug 16, 2004
  2. Valentina Vaneeva

    Imported globals?

    Valentina Vaneeva, Jul 27, 2007, in forum: Python
    Replies:
    0
    Views:
    261
    Valentina Vaneeva
    Jul 27, 2007
  3. Dun Peal
    Replies:
    10
    Views:
    455
    Chris Rebert
    May 3, 2011
  4. Volker Nicolai
    Replies:
    9
    Views:
    931
    Fabian Pilkowski
    Jul 4, 2005
  5. 1989lzhh
    Replies:
    0
    Views:
    43
    1989lzhh
    Jun 7, 2014
Loading...

Share This Page