Local and Global Variable Lookup Weirdness in Python
Skills:
Python for Data80%
Key Takeaways
The video discusses variable lookup rules in Python, specifically how local and global variables are handled, and how assignments later in a function can affect earlier statements.
Full Transcript
hello and welcome i'm james murphy and today we're taking a look at a subtle rule that python has about variable scopes let's play a game what does the function print let's start with an easy one shout out the answers as we go tell me either what it's going to print or what error it's going to give let's start with f what do you think happens when we run it well of course when we run it we get an error specifically a name error okay the first one was really easy what about the second one g is it any different from f well of course we still get an error but it's actually a different error now technically unbound local error derives from name error but i think it might be surprising to many of you that something different happened at all somehow python knew that i was going to assign to x later in the function normally in python outside of a looping context we don't expect statements in a function that are later in the function to affect statements that are earlier in the function it turns out that whether or not a variable like x is determined to be a free variable or a local variable is actually determined at compile time not at runtime in the function f there are no assignments to the variable x so x is determined to be a free variable that means when we say print x it tries to look up x in the global scope and fails in g however the function does contain an assignment for x it says x equals 1. so that means that in the function g x is determined to be a local variable that means that when we try to print x it looks it up in the local scope and hence we get a local error not a global error keeping that in mind let's look at another two examples and see if you get them right what do you think happens when we call h we have defined the global variable y equals 0 before defining the function and then we try to print y in the function go on just shout it out okay this was another easy one it prints zero now what do you think happens for the j function take your time i'll wait okay have you locked your guess in here we go when i run the j function i get another unbound local error now you might look at this and say when i call j we have this global variable y that's defined to be zero so print y should be printing 0 just like in the previous case but that's not how the variable lookup rules work because somewhere in the function j assigns y a value everywhere in the function y is treated as a local variable that means at the beginning when we try to print y it doesn't even try to look it up in the global scope it only looks in the local scope this can be extra confusing because this assignment y equals 1 could theoretically be hundreds of lines later in the function this is yet another reason to avoid using global variables if you can i also want to point out that other languages like c and c plus do not do things this way when i run this function it first prints the global i and then prints the local i that's why we get 0 and then 1 down at the bottom here i even compile with wall and w extra to give me extra warnings and still no warnings to be seen if i want to get a warning for this kind of behavior i have to compile with w shadow the shadow here is referring to the fact that what i'm doing is called variable shadowing if i have a variable and an inner scope like inside a function where i define a variable that has the same name as another variable in an outer scope like the global scope then this is called variable shadowing in this case i would say that this variable i shadows the one in the global scope for obvious reasons you should really try to avoid this if at all possible of course the same goes for python shadowing variables puts you on the fast track to writing bugs in case you were ever wondering this is actually one of the reasons why i define a separate main function rather than just putting things down here any assignments that i do down here are actually in the global scope and that means there's a chance that they're being shadowed i might expect an error if i try to print y here but because the y down here is in the global scope i actually just print that y instead on the other hand if i define a main function then any assignments in here that i do are local to that function that means anything that i do in here i don't have to worry about affecting things in other functions like h now when i run the function i get the expected error in h that's all i've got on this topic now that you know the rules go back and watch the video again and let me know if you get them all right this time if you like the video please consider sharing with your friends subscribing and slapping that like button an odd number of times you
Original Description
Variable lookup rules in Python are weird!
Did you know that a statement in a function can be affected by a LATER assignment? This is a subtle rule of variable lookup in Python.
― mCoding with James Murphy (https://mcoding.io)
Source code: https://github.com/mCodingLLC/VideosSampleCode
Python docs: https://docs.python.org/3/reference/executionmodel.html
SUPPORT ME ⭐
---------------------------------------------------
Patreon: https://patreon.com/mCoding
Paypal: https://www.paypal.com/donate/?hosted_button_id=VJY5SLZ8BJHEE
Other donations: https://mcoding.io/donate
BE ACTIVE IN MY COMMUNITY 😄
---------------------------------------------------
Discord: https://discord.gg/Ye9yJtZQuN
Github: https://github.com/mCodingLLC/
Reddit: https://www.reddit.com/r/mCoding/
Facebook: https://www.facebook.com/james.mcoding
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from mCoding · mCoding · 24 of 60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
▶
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Goodbye, List! Type hinting standard collections - New in Python 3.9
mCoding
Python's comma equals ,= operator?
mCoding
Finding Primes in Python with the Sieve of Eratosthenes
mCoding
Find the First Missing Positive Int | Hard Interview Question on LeetCode
mCoding
JSON Tutorial Python | Basic Python Recipes
mCoding
Simulating Brownian Motion in Python
mCoding
The Single Most Useful Decorator in Python
mCoding
The Fastest Way to Loop in Python - An Unfortunate Truth
mCoding
Numpy Array Broadcasting In Python Explained
mCoding
Brownian Motion Single Path Zoom
mCoding
Brownian Motion Fractal Zoom
mCoding
Magic Methods - Making Python builtins work with your classes
mCoding
50 Million Primes In 5 Seconds - Segmented Sieve of Eratosthenes
mCoding
The Hottest New Feature Coming In Python 3.10 - Structural Pattern Matching / Match Statement
mCoding
How Fast is Python's Sort? Performance Testing
mCoding
C++ First Missing Int, faster than 100%!
mCoding
[April Fools 2021] Python 4.0! New old print, mandatory static typing, StackOverflow integration
mCoding
Python dataclasses will save you HOURS, also featuring attrs
mCoding
C++ Sudoku Solver in 7 minutes using Recursive Backtracking
mCoding
Every PROOF you've seen that .999... = 1 is WRONG
mCoding
Python's sharpest corner is ... plus equals? (+=)
mCoding
Binary Search - A Different Perspective | Python Algorithms
mCoding
The Best Way to Check for Optional Arguments in Python
mCoding
Local and Global Variable Lookup Weirdness in Python
mCoding
Efficient Exponentiation
mCoding
How To Install Python for Data Science
mCoding
0.1 + 0.2 is NOT 0.3 in Most Programming Languages
mCoding
Python 3.10's new type hinting features
mCoding
Python 3.10's Quality of Life improvements
mCoding
Introducing mZips! Python Zip and Zip Longest
mCoding
Match statement tips
mCoding
Using except: is a HUGE mistake
mCoding
Python + YouTube API | Automating descriptions
mCoding
Anaphones, phonetic anagrams
mCoding
Cracking passwords using ONLY response times | Secure Python
mCoding
Python f-strings can do more than you thought. f'{val=}', f'{val!r}', f'{dt:%Y-%m-%d}'
mCoding
Diagnose slow Python code. (Feat. async/await)
mCoding
Python MD5 implementation
mCoding
Salting, peppering, and hashing passwords
mCoding
x to bool conversion in Python, C++, and C
mCoding
You should put this in all your Python scripts | if __name__ == '__main__': ...
mCoding
Find the Skyline Problem with C++ Solution Explained
mCoding
The ONLY C keyword with no C++ equivalent
mCoding
Should you use "not not x" instead of "bool(x)" in Python? (NO!)
mCoding
Multiple Assignments in Python
mCoding
Why I don't like Python's chained comparisons
mCoding
Automated Testing in Python with pytest, tox, and GitHub Actions
mCoding
You can pip install directly from GitHub
mCoding
__new__ vs __init__ in Python
mCoding
Metaclasses in Python
mCoding
The easy way to keep your repos tidy.
mCoding
Which Python @dataclass is best? Feat. Pydantic, NamedTuple, attrs...
mCoding
Python __slots__ and object layout explained
mCoding
C++ cache locality and branch predictability
mCoding
Avoiding import loops in Python
mCoding
25 nooby Python habits you need to ditch
mCoding
Python staticmethod and classmethod
mCoding
Building a Python app with Anvil to email me if my website goes down (includes paid features)
mCoding
31 nooby C++ habits you need to ditch
mCoding
Interviewing the creator of C++, Bjarne Stroustrup
mCoding
More on: Python for Data
View skill →Related Reads
📰
📰
📰
📰
Next.js vs Remix vs SvelteKit: Which Framework Should You Learn?
Dev.to · Etrit Neziri
Had my Frontend Developer interview with Capgemini (Application Developer) today, and I wanted to…
Medium · JavaScript
10 Frontend Developer Tools to Boost Productivity in 2026
Medium · Programming
10 Frontend Developer Tools to Boost Productivity in 2026
Medium · JavaScript
🎓
Tutor Explanation
DeepCamp AI