2

OK I am doing some threading, and I guess when I started doing threading I assumed you can't return values like a definition (its the end of the day and my brain is about to die so maybe this is incorrect and I should start going back to get rid of global variables)

Anyway I have a test program to figure out why I can't modularize my code

a file called config.py

a_variable=0

a file called test_for_sean.py

from config import *
def blah():
  global a_variable
  a_variable=14
  return 0

a file called main.py

from config import *
from test_for_sean import *
print a_variable #this prints correctly
blah()
print a_variable #this is still printing 0....

someone link me to something so I don't kill myself

mhsmith
  • 6,675
  • 3
  • 41
  • 58
Sean Cav
  • 133
  • 1
  • 14
  • I don't recommend doing a ```import *```. Perhaps ```import test_for_sean as tfs```. This will cause all sorts of problems -- like how config.py is executed twice and it fills the global namespace of both scripts its imported into. – Brigand Dec 05 '11 at 23:12
  • @FakeRainBrigand I was looking at this http://www.etsimo.uniovi.es/python/infogami-faq/programming/how-do-i-share-global-variables-across-modules/ is that really wrong? – Sean Cav Dec 05 '11 at 23:17
  • My mistake. I tested with a ```print``` in config.py and it only gets run once. – Brigand Dec 05 '11 at 23:22
  • Do you want a super answer about global variables and modules or just looking for this to work? – César Dec 05 '11 at 23:24
  • @CésarBustíos I mean I am sure I would love to learn the correct way, FakeRainBrigand's solution below seems fairly good, do you know something better – Sean Cav Dec 05 '11 at 23:43
  • 1
    @SeanCav both answers are good for me. I think the point is don't use `from x import *` :) – César Dec 05 '11 at 23:46

3 Answers3

5

When you import variables from a module the names are imported into the current module's namespace, they are not shared between both modules. The global keyword does not allow you to share names between modules, it only allows you to assign to a name that is in the global scope for that module.

To actually share variables between modules you need to access the variable through its module:

a file called config.py

a_variable=0

a file called test_for_sean.py

import config
def blah():
  config.a_variable=14
  return 0

a file called main.py

import config
from test_for_sean import blah
print config.a_variable # prints 0
blah()
print config.a_variable # prints 14
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
4

Try these changes,

config.py,

a_variable = 0

tfs.py (was test_for_sean),

import config

def blah():
    config.a_variable = 14
    return 0

main.py,

import tfs, config

print config.a_variable
tfs.blah()
print config.a_variable

We still import everything from config, but are 'global' variables stay in their own modules. This way we can have global variables but still let main.py define its own a_variable if it needs to.

Brigand
  • 84,529
  • 20
  • 165
  • 173
  • I fixed my code above (thanks to Sean's link). Now it works without globals. Just ```import config``` anywhere you want to use it. – Brigand Dec 05 '11 at 23:26
  • that works, let me see if I can scale it up, I do like the better modularization! Thanks man, I am sad I have but one upvote to give. – Sean Cav Dec 05 '11 at 23:29
2

There is an analogy with a filesystem. It is not a perfect analogy, but helps to understand the problem quickly.

Modules are like directories holding files and these files represent variables and other objects. In modules you are using relative paths. Just write down the absolute paths and the picture will be clear.

Your starting point is:

/my_app/module1/
/my_app/module1/a_variable
/my_app/module2/

A. If you do this in module2:

import a_variable from module1

You are making a copy of the variable a_variable:

/my_app/module1/
/my_app/module1/a_variable
/my_app/module2/
/my_app/module2/a_variable

In this case, when the variables are not mutable, they will get out of sync at the first modification.

B. But when you do this instead:

import module1

You are creating a copy of the path leading to the variable: module1.a_variable

/my_app/module1/
/my_app/module1/a_variable
/my_app/module2/
/my_app/module2/module1 -> ../module1

The result is the same variable in both modules.

VPfB
  • 14,927
  • 6
  • 41
  • 75