69

I'd like to be able to do something like this:

#mymodule
var = None

def load():
    var = something()

Other module(s):

#secondmodule
import mymodule
mymodule.load()

#thirdmodule
from mymodule import var
print var #Shouldn't be None

But I don't know how to reference a modules variable from a function defined in the module.

Is this possible? Or am I going to need to put a global declaration in every place I wan't to use this. Or am I going at this completely wrong?

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
dennmat
  • 2,618
  • 2
  • 17
  • 20

2 Answers2

94

Just change the function definition to:

def load():
    global var # this line has been added to the original code
    var = something()

Global variables are read-only from sibling methods. More accurately unless a variable is specified as global, Python consider it as local, but a read access to a local variable name will reach module-level scope if the name is not present in local scope.

See also use of “global” keyword in python and the doc for more details about the global statement

mit
  • 11,083
  • 11
  • 50
  • 74
Evpok
  • 4,273
  • 3
  • 34
  • 46
  • @dennmat Don't use global variables. If you think you need them it is usually a sign that your design is flawed. – schlamar Nov 15 '12 at 07:31
  • 15
    @schlamar Thanks for the dogma. But no, there are perfectly legitimate use cases for global variables. And it was not the question anyway. – Evpok Nov 15 '12 at 08:22
  • @Evpok Depends ;-) There is the one use case that you want to rewrite members of the current module. But in this case I prefer `sys.modules[__name__].var = something()`. ("Explicit is better than implicit.") – schlamar Nov 15 '12 at 09:09
  • 2
    @schlamar in this particular case I was writing a small tool for myself at home and ran across this problem. In the interest of time and this not being a critical piece of software globals are fine. I agree with Evpok that even in bigger projects there is a time and place for globals just extremely rarely. Even more though because of how python works, these aren't truly "globals". – dennmat Nov 15 '12 at 17:35
  • 24
    @schlamar Is it a joke? This is ugly, a newcomer wouldn't understand it any better than `global`, it unnecessarily expose complex module mechanics, and it requires the import of `sys`, all this just to comply to a questionable dogma, and word of God says “A foolish consistency is the hobgoblin of little minds.”. I prefer `global`. – Evpok May 19 '13 at 10:46
23

You seem to mostly have it. You are missing only the fact that "module-level" variables are called global in Python. (They are not truly global, but only global to the module they are declared in, in other words.)

In any function where you modify a global variable (you want to make the name refer to a different object), it must be declared global. So your load() function needs a global var at the beginning. If you are only using the value of a global variable, or if it is a mutable type such as a list and you are modifying it, but not changing the object that the name points to, you needn't declare it global.

The import statement is, as you have discovered, how you can import a module-level variable from one module into another.

kindall
  • 178,883
  • 35
  • 278
  • 309
  • Thanks for the prompt reply, that was in-fact the solution, helps me understand globals and pythons stacks a little bit more now. – dennmat Aug 15 '11 at 00:54
  • 3
    This answer my doubt, `. If you are only using the value of a global variable, or if it is a mutable type such as a list and you are modifying it, but not changing the object that the name points to, you needn't declare it global.` Thanks @kindall! – swdev Apr 15 '14 at 10:14
  • In my case, I was using global variable in my method, I was not changing it anywhere. On next call, it was empty. not sure why. :( – ssi-anik Nov 23 '16 at 19:10