So, this post was going to be completely different. I was going to do a post on how you can restrict the creation and scoping of certain objects using Python’s
with code blocks. Unfortunately,
with doesn’t restrict scope. Take the following code sample:
with someManager() as i: # do something with i print(i)
This will, unfortunately, work and print whatever
i is. This also plagues
for i in range(10): # do something with i print(i)
This will print 9.
I know that there are some people out there that complain about the insides of code blocks not being restricted, like this:
if True: a = 5 else: a = 6 print(a)
This, I am okay with, even though it goes against typical scoping rules. I’m okay with this because Python doesn’t have a way to declare a variable (except when declaring that it’s using a
nonlocal variable), which means we would have to initialize it with a dummy value before writing the
if block. I don’t like that, and I also don’t like having to declare a variable prior to a code block. So, I’m okay with the lack of normal “block scoping”.
But, you see, there’s a difference between normal block scoping and allowing the values from the opening lines of a
with statement or
for loop out. The
i values in the earlier
for examples are implied to only be useful within the blocks they were created for. This is especially true with
with blocks. A
with block is specifically designed around state control of an object, and the typical object’s state after leaving a
with block is unusable. Exiting generally puts the objects into some sort of “closed” state. That’s the whole point of the
The same basic idea also applies to
for loops. The iterated element only exists for each iteration, but for some reason, the last one gets to just be set free. I don’t like it. There’s no way they’ll change it at this point, but I wish there was a way.
Anyway, that’s my mini rant now. I’ll probably do a similar article as to what I had planned this week, but just show a different method for accomplishing it.