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.
How to make variables global by default, Python 3.11
design - What are the considerations between a class variable and a global variable - Software Engineering Stack Exchange
Global variable Python classes - Stack Overflow
Painful details of variable scope mixed with classes
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?
Accessibility is not the only thing. There's also scope and context.
A class variable (or static member as they are called in many languages) is tied to a particular domain. It should make sense to make it a member of that class because it is meaningful in the context of that class.
Example: class Cat may have a static member count that keeps the number of Cat instances at any particular time. You could instead have a global variable catCount but that would be less OO. Obviously the number of Cat instances is closely related to the Cat class, hence it makes sense to make it a Cat class member. This also narrows the scope of the variable to the class members of Cat (you must type Cat. first for it to become available). Tight scope is always a good thing, a global variable catCount would be meaningless outside the scope of the Cat class and thus noisy.
It's about locality
A class defines a region of locality, within which things "belong together". Such locality is useful for understanding what relates to what (or does not).
Global variables do not give you this effect.
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
I apologize if my terminology is wrong, I'm still fairly new to Python. This question has been asked before but I wasn't able to comprehend the answer.
I'm having trouble understanding why using Global variables is a bad practice, but instantiating a class instance to a Global variable isn't. I understand that reading from Global variables is fine, but classes seem to be used for changing states, which means if I modify an instantiated class variable I'm essentially changing a Global.
For example:
my_variable = MyClass("Hello")
def a_function():
MyClass.my_attribute = "World"vs
my_variable = "Hello"
def a_function():
Global my_variable = "World"