Reputation: 8406
I have a JSON file that I am using as a datastore in a small game I am using as a way to learn Python.
I am proficient in a number of other languages.
I have several classes that want read access to the JSON so I want to load the JSON from the file into a variable and then allow the other classes to access the variable via getters and setters, because each class wants different parts of the JSON.
This sounds like a job for a Singleton. I understood that a Python Module behaves like a singleton.
However, when I import the Module into my classes the variable resets?
Here is a very cut down example:
Module:- state_manager
x=45
def set_x(value):
x=value
def get_x():
return x
Class:- Game
import Player
import state_manager
value = state_manager.get_x()
Class:- Player
import state_manager
state_manager.set_x(12)
By setting breakpoints I can see that when Player is imported by Game that Player
sets the value of x
in state_manager
to 12.
But when I look at the value of x
returned to Game using state_manager.get_x()
I get 45.
Why is this?
What is the correct way in Python to create a Module or Object that can be shared among other classes?
I realise I can construct a Singleton myself but I thought I'd use the features of Python.
Upvotes: 3
Views: 83
Reputation: 24052
You need to declare x
global in any function that attempts to set it globally:
def set_x(value):
global x
x=value
Without the global declaration, x
is just a function-local variable.
In general, if a function assigns to a variable, anywhere in the function, then that variable is local unless it is explicitly declared global
(or nonlocal
). If a function only reads a variable, without setting it, then the variable is taken from a higher scope (e.g., a global, or an up-level reference).
Upvotes: 2
Reputation: 25855
By setting breakpoints I can see that when Player is imported by Game that Player sets the value of x in state_manager to 12.
I am fairly sure that you're doing something wrong in your inspection, because the set_x
function, at least as you quoted it...
x=45
def set_x(value):
x=value
...does not do what you think it does. Since x
is being assigned to in the scope of set_x
, it does not refer to the global (module-level) variable x
, but to a local variable x
that is immediately discarded as part of the stack frame when set_x
returns. The existence of static assignments is effectively how local variables are declared in Python. The fix is to declare x
as referring to the global variable:
x=45
def set_x(value):
global x
x=value
Upvotes: 3