Global variables and modules

Discussion in 'Python' started by dkeeney@travelbyroad.net, Dec 24, 2004.

  1. Guest

    I have a newby type question on how global variables work between
    modules.

    I have a module test2.py that defines a global variable as well as two
    functions to operate on that variable. A script test1.py imports the
    three names and prints out values of the global between operations, and
    the results aren't what I expected.

    Here is the module, test2.py
    ------------------------------------
    glbl = 25

    def inc_glbl():
    global glbl
    glbl += 1

    def get_glbl():
    global glbl
    return glbl
    ------------------------------------

    and here is the test script, test1.py
    -------------------------------------

    from test2 import glbl, inc_glbl, get_glbl

    print 'glbl orig ', glbl

    inc_glbl()
    print 'glbl postinc ', glbl

    new = get_glbl()
    print 'glbl from func ', new
    --------------------------------------
    I would expect the three values to be ( 25, 26, 26 ), but what I get is
    c:\projects\pitcher_model>test1.py
    glbl orig 25
    glbl postinc 25
    glbl from func 26

    ---------
    It seems that the references to 'glbl' are seeing a local copy, rather
    than the original. This is not what the literature says should be
    happening. I am looking for a way to share data between modules. Can
    you advise me on my error? I am using Python 2.3.2 from ActiveState,
    on Windows XP Pro.

    Thank you
    David
     
    , Dec 24, 2004
    #1
    1. Advertising

  2. Binu K S Guest

    Re: Global variables and modules

    Add these lines to test1.py and see what you get:
    import test2
    print 'test2.glbl postinc ', test2.glbl

    This will work as you expect.

    Next try chaning glbl in test2 to a list (a mutable type).

    test2.py:
    glbl = [25]

    def inc_glbl():
    global glbl
    glbl[0] = glbl[0] + 1

    def get_glbl():
    global glbl
    return glbl[0]

    test1.py:
    from test2 import glbl, inc_glbl, get_glbl

    print 'glbl orig ', glbl[0]

    inc_glbl()
    print 'glbl postinc ', glbl[0]

    new = get_glbl()
    print 'glbl from func ', new

    import test2
    print 'test2.glbl postinc ', test2.glbl

    [kbinu@localhost kbinu]$ python2.2 test.py
    glbl orig 25
    glbl postinc 26
    glbl from func 26
    test2.glbl postinc [26]


    On 23 Dec 2004 21:43:40 -0800,
    <> wrote:
    >
    > I have a newby type question on how global variables work between
    > modules.
    >
    > I have a module test2.py that defines a global variable as well as two
    > functions to operate on that variable. A script test1.py imports the
    > three names and prints out values of the global between operations, and
    > the results aren't what I expected.
    >
    > Here is the module, test2.py
    > ------------------------------------
    > glbl = 25
    >
    > def inc_glbl():
    > global glbl
    > glbl += 1
    >
    > def get_glbl():
    > global glbl
    > return glbl
    > ------------------------------------
    >
    > and here is the test script, test1.py
    > -------------------------------------
    >
    > from test2 import glbl, inc_glbl, get_glbl
    >
    > print 'glbl orig ', glbl
    >
    > inc_glbl()
    > print 'glbl postinc ', glbl
    >
    > new = get_glbl()
    > print 'glbl from func ', new
    > --------------------------------------
    > I would expect the three values to be ( 25, 26, 26 ), but what I get is
    > c:\projects\pitcher_model>test1.py
    > glbl orig 25
    > glbl postinc 25
    > glbl from func 26
    >
    > ---------
    > It seems that the references to 'glbl' are seeing a local copy, rather
    > than the original. This is not what the literature says should be
    > happening. I am looking for a way to share data between modules. Can
    > you advise me on my error? I am using Python 2.3.2 from ActiveState,
    > on Windows XP Pro.
    >
    > Thank you
    > David
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
     
    Binu K S, Dec 24, 2004
    #2
    1. Advertising

  3. <> wrote:
    ...
    > and here is the test script, test1.py
    > -------------------------------------
    >
    > from test2 import glbl, inc_glbl, get_glbl


    Think of this as roughly equivalent to:

    import locl
    glbl = test2.glbl

    and so on. That is, after the 'from test2 import', the two names
    test1.glbl and test2.glbl refer to the same object. But if you now
    rebind name test2.glbl to refer to a distinct object, that of course has
    no effect on name test1.glbl.

    > I would expect the three values to be ( 25, 26, 26 ), but what I get is


    Why? Take an equivalent:

    a = 25
    b = a
    a = 26

    would you now expect name b to be magically rebound to 26? If so, then
    you have a very peculiar mental model for name/value correspondences,
    one that doesn't happen to hold in any language I know, surely not in
    Python. To repeat a commonly used metaphor: think of names as post-it
    notes that may be attached to some piece of furniture, and moved from
    one to another. The notes are NOT attached to each other, but rather to
    the objects: moving one post-it does not affect other post-its.

    > It seems that the references to 'glbl' are seeing a local copy, rather


    No copy whatsoever is involved. After the assignment (binding) you do
    with 'from test2 import', names test1.glbl and test2.glbl refer to the
    same object (value). If you now rebind either name, the other is
    unaffected.

    > than the original. This is not what the literature says should be
    > happening.


    If you can point to sentences in "the literature" which have misled you
    into believing a different behavior would be expected, I'll do my best
    to fix those sentences (as a book and article author, editor, reviewer,
    and Python contributor). While the Python docs, including books &c, are
    far from perfect, I doubt there is any such blooper left in them.

    > I am looking for a way to share data between modules. Can


    If you really must, consider using a container object. The most
    suitable container object for these tasks is often a module. I.e.,
    code, in test1:

    import test2

    and then refer to test2.glbl throughout. I.e., forget 'from', use
    'import'.

    As I wrote in Python in a Nutshell, p. 120, last paragraph before
    "Module Loading":
    """
    In general, the import statement is a better choice than the from
    statement. I suggest you think of the from statement [...] as [a]
    convenience meant only for occasional use in interactive Python
    sessions. If you always access module M with the statement import M,
    and always access M's attributes with explicit syntax M.A, your code
    will be slightly less concise, but far clearer and more readable.
    """

    I don't know how I could have put this advice more strongly or more
    directly (I continue with explanations about the cases in which 'from'
    is instead appropriate, chiefly getting single modules from packages).

    Giving strong direct advice, rather than just reference info, in a book
    of the "in a Nutshell" series, is not common, but I do it quite a bit;
    after all, "how does Python work exactly", e.g. the fact that 'from X
    import Y' is almost the same as 'Y = X.Y', is pretty simple to explain,
    and so takes up little space -- OTOH, the consequences of this, such as
    "thus, generally, don't use 'from', use 'import'" may not be obvious to
    readers, so I point them out directly.

    Of course, that doesn't help much if people don't _read_ it;-).


    Alex
     
    Alex Martelli, Dec 24, 2004
    #3
  4. Guest

    Re: Global variables and modules

    Thank you to both of you for your assistance.

    Using the qualified 'test2.glbl' form of the variable name gives the
    result I need. The concepts of binding and rebinding, as programming
    concerns, are new to me; I will have to study that further.
    Thank you again, and Merry Christmas.

    David
     
    , Dec 24, 2004
    #4
  5. Alex Martelli said unto the world upon 2004-12-24 03:23:
    > <> wrote:


    <SNIP>

    > If you really must, consider using a container object. The most
    > suitable container object for these tasks is often a module. I.e.,
    > code, in test1:
    >
    > import test2
    >
    > and then refer to test2.glbl throughout. I.e., forget 'from', use
    > 'import'.
    >
    > As I wrote in Python in a Nutshell, p. 120, last paragraph before
    > "Module Loading":
    > """
    > In general, the import statement is a better choice than the from
    > statement. I suggest you think of the from statement [...] as [a]
    > convenience meant only for occasional use in interactive Python
    > sessions. If you always access module M with the statement import M,
    > and always access M's attributes with explicit syntax M.A, your code
    > will be slightly less concise, but far clearer and more readable.
    > """
    >
    > I don't know how I could have put this advice more strongly or more
    > directly (I continue with explanations about the cases in which 'from'
    > is instead appropriate, chiefly getting single modules from packages).
    >
    > Giving strong direct advice, rather than just reference info, in a book
    > of the "in a Nutshell" series, is not common, but I do it quite a bit;
    > after all, "how does Python work exactly", e.g. the fact that 'from X
    > import Y' is almost the same as 'Y = X.Y', is pretty simple to explain,
    > and so takes up little space -- OTOH, the consequences of this, such as
    > "thus, generally, don't use 'from', use 'import'" may not be obvious to
    > readers, so I point them out directly.
    >
    > Of course, that doesn't help much if people don't _read_ it;-).
    >
    >
    > Alex


    Hi all,

    I'm quite fond of the

    import really_long_module_name as rlmn

    idiom. I use it all the time for some utility modules that I have
    developed, where I like the module to have a descriptive name, but I
    don't feel like burning line-length on retyping it all the time. If you
    adopt a standard set of abbreviations ('fu' for 'fileutils', etc.) you
    get less typing while preserving the advantages of clarity and
    readability that the unmodified import provides. (And, of course, both
    protect your namespace from the clobbering that will eventually arise
    with use of from.)

    I don't think the relevant section of Nutshell mentions this idiom.
    However, I don't have my copy with me (seasonal travel, and all), so
    apologies if my memory leads me astray.

    For what its worth, I'm glad for the advice in Nutshell. It transforms
    the book from a useful thing for those who like dead-tree references
    into a text one can actually read (as opposed to merely consult quickly).

    Best to all,

    Brian vdB
     
    Brian van den Broek, Dec 24, 2004
    #5
  6. Brian van den Broek <> wrote:

    > I'm quite fond of the
    >
    > import really_long_module_name as rlmn

    ...
    > I don't think the relevant section of Nutshell mentions this idiom.
    > However, I don't have my copy with me (seasonal travel, and all), so
    > apologies if my memory leads me astray.


    Apologies accepted -- it's right on p. 117, at the first mention of the
    import statement. Maybe I'm not giving it enough prominence, though,
    nor advice about how to use it...


    Alex
     
    Alex Martelli, Dec 24, 2004
    #6
  7. John Machin Guest

    Re: Global variables and modules

    wrote:
    > I have a newby type question on how global variables work between
    > modules.
    >
    > I have a module test2.py that defines a global variable as well as

    two
    > functions to operate on that variable. A script test1.py imports the
    > three names and prints out values of the global between operations,

    and
    > the results aren't what I expected.

    [snip]
    > I am looking for a way to share data between modules. Can
    > you advise me on my error?


    Yes. Your error is that you are looking at global variables as "a way
    to share data between modules". The advice is "Don't do that". Limited
    use of global variables whose values are updated is barely tolerable
    within a single module that will be executed by a single thread of a
    single process. Otherwise you can end up with monstrosities like
    database "forms" applications with hundreds of globals. Google for
    concepts like "modularity" and "information hiding". Then read about
    OOP.
     
    John Machin, Dec 24, 2004
    #7
    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. Fuming Wang
    Replies:
    7
    Views:
    336
    =?iso-8859-1?q?Fran=E7ois_Pinard?=
    Jul 17, 2003
  2. KN
    Replies:
    1
    Views:
    266
    Jerry Sievers
    Apr 17, 2004
  3. Aaron Deskins

    Global variables in modules/functions

    Aaron Deskins, Nov 19, 2004, in forum: Python
    Replies:
    7
    Views:
    4,265
    Aaron Deskins
    Nov 22, 2004
  4. Bart
    Replies:
    4
    Views:
    479
    Bart van Deenen
    Feb 23, 2005
  5. January Weiner

    Modules, global variables and such

    January Weiner, Feb 10, 2008, in forum: Perl Misc
    Replies:
    16
    Views:
    177
    January Weiner
    Mar 2, 2008
Loading...

Share This Page