By declaring it global inside the function that accesses it:
g_c = 0
class TestClass():
def run(self):
global g_c
for i in range(10):
g_c = 1
print(g_c)
The Python documentation says this, about the global statement:
Answer from unwind on Stack OverflowThe global statement is a declaration which holds for the entire current code block.
By declaring it global inside the function that accesses it:
g_c = 0
class TestClass():
def run(self):
global g_c
for i in range(10):
g_c = 1
print(g_c)
The Python documentation says this, about the global statement:
The global statement is a declaration which holds for the entire current code block.
You need to move the global declaration inside your function:
class TestClass():
def run(self):
global g_c
for i in range(10):
g_c = 1
print(g_c)
The statement tells the Python compiler that any assignments (and other binding actions) to that name are to alter the value in the global namespace; the default is to put any name that is being assigned to anywhere in a function, in the local namespace. The statement only applies to the current scope.
Since you are never assigning to g_c in the class body, putting the statement there has no effect. The global statement only ever applies to the scope it is used in, never to any nested scopes. See the global statement documentation, which opens with:
The global statement is a declaration which holds for the entire current code block.
Nested functions and classes are not part of the current code block.
I'll insert the obligatory warning against using globals to share changing state here: don't do it, this makes it harder to reason about the state of your code, harder to test, harder to refactor, etc. If you must share a changing singleton state (one value in the whole program) then at least use a class attribute:
class TestClass():
g_c = 0
def run(self):
for i in range(10):
TestClass.g_c = 1
print(TestClass.g_c) # or print(self.g_c)
t = TestClass()
t.run()
print(TestClass.g_c)
Note how we can still access the same value from the outside, namespaced to the TestClass namespace.
object oriented - Module with globals or Class with attributes? - Software Engineering Stack Exchange
Painful details of variable scope mixed with classes
How to make variables global by default, Python 3.11
Global variables in python classes
How do I make a global variable in Python?
What is a global variable in Python, and why do I need it?
What is variable scope in Python?
Videos
Hey this question have a few sub-questions:
#1 Why this code returns name 'y' is not defined is it possible to add something like global or public tag to variables in python?
class Test: y = 1 def __init__(self): self.__x = 1 def print_me(self): print(y) t = Test() t.print_me()
#2 Why this code returns paradoxical response Test2.test() takes 0 positional arguments but 1 was given?
class Test2: def test(): u = 5 t2 = Test2() t2.test()
#3 Why class methods can define class variables in python?
There's no real difference between a package-level global (version one for you) and a class variable. They're both implementations of a situation where the state is stored in a single place.
Typically you want to avoid this for many reasons, a few including:
- It's difficult to track who is changing state in the case that these global values are visible to the outside world.
- It's difficult to change code later on if you need to track multiple states at once, like if you moved to a concurrent environment.
- There's no way to get referential transparency - the behaviour of a function depends on when you call it. This makes testing very difficult, because writing solid tests means you have a way to guarantee resetting the state.
I'd recommend using an object approach with instance-level variables instead of global/class-level state:
class MyClass:
def __init__(self):
self._state_var = 0
def do_something(self, arg1):
if arg1:
self._state_var = 1
def say_hello(self):
if self._state_var:
print("Hello!")
I'd also recommend going against the current practice. The more you add to the pile of bad code, the more places there are for things to go wrong. If you build your code according to good software engineering practices, you're less likely to have issues later on.
And who knows, maybe you writing good code will encourage other people to do the same!
Globals in Python are only global to the module where they belong to, not across different modules. So the scope of STATE_VAR in both of your examples is essentially the same!
A class is required when you need (or expect to need) more than one instance of the abstraction formed by the module. If you are sure your program will not need this in the near future, a class likely does not bring you any benefit, you can stay with modules and "module globals" without any significant drawback.
For more details on when or when not to use classes in Python, see also:
When should I be using classes in Python.
Classes vs. modules in Python