Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python global variables don't seem to work across modules

Code

I'd like to use a global variable in other modules with having changes to its value "propagated" to the other modules.

a.py:

x="fail"
def changeX():
    global x
    x="ok"

b.py:

from a import x, changeX
changeX()
print x

If I run b.py, I'd want it to print "ok", but it really prints "fail".

Questions

  1. Why is that?
  2. How can I make it print "ok" instead?

(Running python-2.7)

like image 466
escitalopram Avatar asked Nov 15 '12 17:11

escitalopram


People also ask

Can global variables be used across modules in Python?

The best way to share global variables across modules across a single program is to create a config module. Just import the config module in all modules of your application; the module then becomes available as a global name.

Are global variables shared between modules?

Globals in Python are global to a module, not across all modules. (Unlike C, where a global is the same across all implementation files unless you explicitly make it static.). If you need truly global variables from imported modules, you can set those at an attribute of the module where you're importing it.

How will you share global variables across modules?

To share global variables across modules within a single program, create a special module. Import the config module in all modules of your application. The module will be available as a global variable across modules.

Why should we not use global variables in Python?

The reason global variables are bad is that they enable functions to have hidden (non-obvious, surprising, hard to detect, hard to diagnose) side effects, leading to an increase in complexity, potentially leading to Spaghetti code.


1 Answers

In short: you can't make it print "ok" without modifying the code.

from a import x, changeX is equivalent to:

import a
x = a.x
changeX = a.changeX

In other words, from a import x doesn't create an x that indirects to a.x, it creates a new global variable x in the b module with the current value of a.x. From that it follows that later changes to a.x do not affect b.x.

To make your code work as intended, simply change the code in b.py to import a:

import a
a.changeX()
print a.x

You will have less cluttered imports, easier to read code (because it's clear what identifier comes from where without looking at the list of imports), less problems with circular imports (because not all identifiers are needed at once), and a better chance for tools like reload to work.

like image 181
user4815162342 Avatar answered Sep 28 '22 11:09

user4815162342