Every variable assigned inside a function is local to that function by default, existing only for the duration of that call and invisible outside it — this is why two different functions can each use a variable with the same name without conflicting. A function can read a global variable without any special syntax, but assigning to a name inside a function makes Python treat it as local for the entire function body, unless you explicitly declare it with the global keyword first, telling Python to modify the module-level variable instead of creating a new local one.
1Understanding Scope (Global / Local)
Every variable assigned inside a function is local to that function by default, existing only for the duration of that call and invisible outside it — this is why two different functions can each use a variable with the same name without conflicting. A function can read a global variable without any special syntax, but assigning to a name inside a function makes Python treat it as local for the entire function body, unless you explicitly declare it with the global keyword first, telling Python to modify the module-level variable instead of creating a new local one.
Needing the global keyword inside a function is often a sign that the logic would be cleaner as a value passed in and returned out, rather than a function silently mutating shared state — reach for it deliberately, not as a first resort.
counter = 0
def increment():
global counter
counter += 1
increment()
increment()
print(counter)2Practical Example
Here is a real-world application of Scope (Global / Local) showing how it is used in production Python code.
def make_local():
message = "I'm local"
print(message)
make_local()
print("message" in dir())3Best Practices
Follow these guidelines when working with Scope (Global / Local):
1. Prefer passing values in as parameters and returning results out, over mutating global variables from inside functions
2. Use the global keyword explicitly and sparingly, only when a function genuinely needs to modify module-level state
3. Avoid shadowing a global name with a same-named local variable unintentionally — it's a common source of confusing bugs, especially in longer functions
Tip: Needing the global keyword inside a function is often a sign that the logic would be cleaner as a value passed in and returned out, rather than a function silently mutating shared state — reach for it deliberately, not as a first resort.
counter = 0
def increment():
global counter
counter += 1
increment()
increment()
print(counter)