INS
INS

Reputation: 10820

python import-ed variable keeps the same value although it is changing

I have the following python code which in my opinion behaves strangely:

Imported module:

# ChangeVar.py
def Print1():
    print "1--"

def Print2():
    print "2--"

Print=Print1

def Change():
    global Print
    Print=Print2

Main module:

#UseVar.py
from ChangeVar import *

Print()
Print()

Change()


Print()
Print()

I expect this code to print the follwing:

1--
1--
2--
2--

But what I get instead is:

1--
1--
1--
1--

Could someone point me to the right part of the python reference or explain why I don't get the expected behavior?

Thanks,

Iulian

Upvotes: 3

Views: 428

Answers (2)

Gareth Latty
Gareth Latty

Reputation: 88977

Python's global is global to the module only.

import ChangeVar

ChangeVar.Print()
ChangeVar.Print()

ChangeVar.Change()

ChangeVar.Print()
ChangeVar.Print()

This will work, however, reconsider your use of global - it's universally bad practice. There should be a cleaner way to do what you want. Consider using a class inside your module.

# ChangeVar.py
class ChangeVar(object):
    def __init__(self):
        self.Print=self.Print1

    def Print1(self):
        print "1--"

    def Print2(self):
        print "2--"

    def Change(self):
        self.Print=self.Print2

Used as so:

#UseVar.py
from ChangeVar import ChangeVar

cv = ChangeVar()
cv.Print()
cv.Print()

cv.Change()

cv.Print()
cv.Print()

I would also like to note that according to the Python style guide, lowercase_with_underscores is the preferred naming style for functions, and lowercase for module names.

Upvotes: 2

Thomas K
Thomas K

Reputation: 40330

When you do from ChangeVar import *, you create a name Print in your main module referring to what Print is currently set as in ChangeVar. But that's a separate name pointing to the same function, so calling Change doesn't update it in your main module.

There are two ways round it:

  • You can do import ChangeVar and then call ChangeVar.Print(). Because this uses the name in ChangeVar, it is affected by ChangeVar.Change(), as @Lattyware says.
  • You can create a function Print which calls Print1 or Print2 depending on what some other variable is set to.

Upvotes: 2

Related Questions