I had this same question, and found out that you absolutely can!
It's not as clean as the c style blocks, but through two quirks of python we can make it serve our purposes.
The Quirks:
- Whatever code is inside a class runs immediately, even if the class is never used.
- You can reuse the name of a class as many times as you want.
Here's your example:
class DoStuff:
i = 1
# Do stuff
# local variable i is destroyed
class DoStuff:
i = 7
# Do more stuff
# local variable i is destroyed
To fully represent the flexibility here, see this example. I've named the class "Scope", because that's probably what I'd call it to differentiate from other named classes.
Note that "Scope" can of course be anything.
I'd recommend you stick with one name for the entire project and add that name to your documentation, so that there is an understanding that this is a special name that should never ever be instantiated.
outer = 1
class Scope:
inner = outer
print("runs first ---")
print("outer %d" % outer)
print("inner %d" % inner)
class Scope:
inner = outer + 1
print("runs second ---")
print("outer %d" % outer)
print("inner %d" % inner)
print("runs last ---")
print("outer %d" % outer)
print("inner %d" % inner) # This will give an error. Inner does not exist in this scope!
Output:
runs first ---
outer 1
inner 1
runs second ---
outer 1
inner 2
runs last ---
outer 1
Traceback (most recent call last):
File "test.py", line 18, in <module>
print("inner %d" % inner) # This will give an error. Inner does not exist in this scope!
NameError: name 'inner' is not defined
So it is doable - let's take a look at the benefits / downsides tradeoffs.
Benefits:
- Code remains linear and no unnecessary leaps in logic are needed to follow the code flow. This linearity will make it easier for newcomers to read and understand what a section of code actually does.
- Code is self-documenting to future coders that this code is only used in this one place, making it easier to edit, as the coder will not need to do an unnecessary search to find other instances.
Downsides:
- We're using quirks of Python to make this work, and I sense that this very idea of limiting scope as opposed to creating new one-time-use functions is not something that Python programmers tend to do. This may cause tensions in the workplace, or result in complaints of using a hack as opposed to following conventions on creating small functions whether or not something is used more than once.
- If you leave the project and new programmers come onboard and see this code, they will probably be confused initially. Some documentation will be needed in order to set expectations, and care must be taken to make sure the explanation in the documentation remains accurate.
I think this is a worthwhile effort for all code where you'd like to limit the scope but there are not multiple places this code is used, or it is not yet clear how to write a generic function to address all those situations.
If anyone reading this feels there are other tradeoffs, comment here and I'll make sure they're represented in the "Downsides" section.
Here's some more discussion around this convention, which has been preferred by John Carmack, Jonathan Blow, and Casey Muratori.
https://news.ycombinator.com/item?id=12120752