diff --git a/README.md b/README.md index 8db5b61..50a7719 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/). For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter). -_1777 TILs and counting..._ +_1778 TILs and counting..._ See some of the other learning resources I work on: @@ -1048,6 +1048,7 @@ If you've learned something here, support my efforts writing daily TILs by - [Access Instance Variables](python/access-instance-variables.md) - [Access Most Recent Return Value In REPL](python/access-most-recent-return-value-in-repl.md) +- [Access Variables Outside Loop Scope](python/access-variables-outside-loop-scope.md) - [Avoid Modification With Frozen Dataclass](python/avoid-modification-with-frozen-dataclass.md) - [Break Debugger On First Line Of Program](python/break-debugger-on-first-line-of-program.md) - [Check If Package Is Installed With Pip](python/check-if-package-is-installed-with-pip.md) diff --git a/python/access-variables-outside-loop-scope.md b/python/access-variables-outside-loop-scope.md new file mode 100644 index 0000000..b4f926b --- /dev/null +++ b/python/access-variables-outside-loop-scope.md @@ -0,0 +1,44 @@ +# Access Variables Outside Loop Scope + +Here is a function that loops over a list to find the first occurrence of a +falsy value. + +```python +def find_false(self): + for item in self.items: + item_type = type(item) + print(f"Current item: {item} ({item_type})") + if not item: + break + + print(f"First false item: {item} ({item_type})") +``` + +Notice how at the end of the function, outside of the loop, I am able to access +both `item` (defined in the loop definition) and `item_type` (defined within the +loop's body). + +Both of these variables are defined, by the loop, in _function scope_ and are +accessible anywhere in the function after they have been defined. + +The title of this TIL is a bit of a misnomer because Python doesn't have the +concept of a _loop scope_. There are two levels of scope in Python -- +module/global scope and function scope. + +I spend most of my time writing Ruby which also has _block scope_, so Python's +simplified two-level scoping took me by surprise. + +Though the code sample above is contrived, this function scope assignment can be +taken advantage of with loop definitions in scenarios where you want to know +what the last `item` defined was before the loop terminated. + +```python +for submission in submissions: + if passes(submission, criteria): + break +else: + raise ValueError("No submissions that meet given criteria") + +print(f"Submit first passing submission: {submission.id}") +submit(submission) +```