Python global variable problem

Started by
10 comments, last by King Mir 11 years, 10 months ago
So I have 3 files like so:
[source lang="python"]#Test1.py
import Test2, Test.Test3

if __name__ == '__main__':
Test2.initVal()
print Test2.getVal()
Test.Test3.func()[/source]
[source lang="python"]#Test2.py
val = {}

def initVal():
val[0] = 1

def getVal():
return val[0][/source]
[source lang="python"]#Test/Test3.py
import Blobs.Test2

def func():
print Blobs.Test2.getVal() #blobs is top level package[/source]

This prints 1, then gives me an exception, because func() sees val as empty the second time. How do I make it see the properly changed variable?

EDIT: clarified behavior
Advertisement
This is because you need to specifiy you are using a global.

Your initVal and getVal functions should look like this:


def initVal():
global val
val[0] = 1

def getVal():
global val
return val[0]

This is because you need to specifiy you are using a global.

Your initVal and getVal functions should look like this:


def initVal():
global val
val[0] = 1

def getVal():
global val
return val[0]

Tried it, didn't work.

From what I understand, global is used to spefiy that assign ment should overide a global variable. It would be needed to make Test2.getVal() work the first time, if the dictionary was reassigned, instead of having a key added. Here Test2.getVal() works, just not Blobs.Test2.getVal(),
This is working fine for me, both function return 1. What is the exact error. What do you mean by it does not work? Could you provide the project structure? (packages layout)


[background=rgb(250, 251, 252)]From what I understand, global is used to spefiy that assign ment should overide a global variable. It would be needed to make Test2.getVal() work the first time, if the dictionary was reassigned, instead of having a key added[/background]


[/quote]

I'm not sure to understand what you mean. Global is used to tell the interpreter that you are not dealing with a new object but reusing/overriding one that was defined at global scope when the module was imported the first time. So in any case (assignement or adding a key), "global val" is needed.
The package layout is that Test3.py is in a package Test, and everything is in a package Blob (including package Test).

The error is that it prints 1, then throws a key error for the second call.
I also found this surprising behaviour:

[source lang="python"]#Test5.py
import Blobs.Test2

def func2(atype):
print atype
print Blobs.Test2.TestClass
print atype == Blobs.Test2.TestClass[/source]
[source lang="python"]#Test2.py
class TestClass (object):
pass[/source]

[source lang="python"]import Test5, Test2

if __name__ == '__main__':
Test5.func2(Test2.TestClass)[/source]

This prints 2 different class paths, followed by False. Why? It's the same class, just a different way of getting to it.
It seems all those issues come from the fact that you are importing the Test2.py differently.

Sometimes you use import Blobs.Test2 and sometimes import Test2

Python treats it as if it were two different modules. To fix your problem always use import Blobs.xxx (where xxx is the name of your module/package)
I see. Thanks.

That's very annoying. It means I'll have to use absolute paths for all imports. And probably use from import for brevity,
If you plan to distribute the package (or use it in different projects), yes. Otherwise you can just omit the package name (in this case you should even remove the __ini__.py as it is not a real package anymore).
Do you mean leave the folder structure, but remove the __init__.py from the Test folder? Or remove the Blobs package but leave Test intact?

Right now I have a package, like Test in this question, that needs to call a function 1 package up. Eventually I might add enough to the program that that function and related code would warrant a package of its own. So the solution needs to have that in mind.

Though I am using packages for organisational convenience, not really to be able to reuse the code in another program.

This topic is closed to new replies.

Advertisement