Preamble: I feel I probably have wasted so much time for a simple situation...
Now, I am making a game with pygame, and at some point, I wanted to split fil
TLDR: Use import configuration
and fully qualified names, e.g. configuration.running
.
If a function inside configuration
needs to modify a top-level value, it must use global
.
def decrease_HP(self):
global running
self.HP -= 1
print("-1 HP", "Current HP:", self.HP)
if self.HP <= 0:
running = False
Using from configurations import running
(or equivalent via ... import *
) in main
binds the value of configurations.running
to a new name main.running
. While these names initially share the same value, re-assigning either breaks this equivalency. This is exactly the same as rebinding other names.
>>> a = 1
>>> b = a # a and b point to same value
>>> a == b
True
>>> b = 2 # rebind only b
>>> a == b
False
To make changes visible across the application, one should use an object an modify its value. A common example are containers, such as lists.
>>> a = [1]
>>> b = a # a and b point to same value
>>> a == b
True
>>> b[0] = 2 # modify content of value of b
>>> a == b
True
>>> a[0] == b[0] # content is the same
True
Since modules are objects, it is possible to use them directly to store state.
>>> import configuration
>>> b = configuration # configuration and b point to same value
>>> configuration == b
True
>>> b.running = False # modify content of value of b
>>> configuration == b
True
>>> configuration.running == b.running # content is the same
True
Functions have local scope. Any assignment to a name inside a function implicitly declares the target as local to the function.
>>> running = True
>>> def stop():
... running = False
...
>>> stop() # changes only running inside the function
>>> running
True
This can be made visible by accessing a local name before it has a value.
>>> running = True
>>> def stop():
... print(running)
... running = False
...
>>> stop()
UnboundLocalError: local variable 'running' referenced before assignment
By declaring the name global
, no local name is created. The global value can be directly read and written.
>>> running = True
>>> def stop():
... global running
... print(running)
... running = False
...
>>> stop() # will print the global value before the change
True
>>> running # global value was changed
False