4 ms·
Can you increase indentation arbitrarily, though? Like, say I want to initialize some data for a loop, that I wouldn't need later, could I: main_scope_stu
by neutronicus 16y ago
Can you increase indentation arbitrarily, though? Like, say I want to initialize some data for a loop, that I wouldn't need later, could I:
main_scope_stuff()
c = create_context()
for foo in foos:
do_something(foo, c)
do_other_thing(foo, c)
accumulate(foos, c)
more_main_scope_stuff()
to emphasize that c was only important to the loop and the call to "accumulate"?
- Locke1689 16y agoOf course it's possible to increase indentation arbitrarily: simply create a new function. Any programmer should know that too many immediate levels of lexical context is bound to confuse the reader anyway. I'm not really sure what you're trying to show with that code, though. Is your objection that every do_ function is requiring a context? Edit: I see what the parent was saying now, see bottom comment. Also, see StavrosK's comment if you're fine using Python 2.5 (released 2006).
- neutronicus 16y agoI want to communicate, using indentation, that more_main_scope_stuff() and subsequent code do not depend on c. c is conceptually part of the loop, and not of the surrounding code. (Like the initialization statement in C/C++). The code I wrote does this (because c is 1 indentation level deeper than the main_scope functions). I do not know if it is legal Python to simply increase indentation level to demarcate a new scope, but I suspect it is not, and it is certainly not common practice. This is really a minor gripe - but then again so are the article's - it's pretty easy to tell a binding from a function call.
- Locke1689 16y agoAh, I see -- this is a really good point, thanks for bringing it up. You're right, one can not arbitrarily increase scope in Python. The most common way I've seen of demarcating this kind of structure is actually using a blank line. For example, the code would instead look more like: c = create_context() for foo in foos: do_something(foo, c) do_other_thing(foo, c) accumulate(foos, c) do_other_stuff One could also throw the separate stuff into a new function.
- neutronicus 16y agoOne could also throw the separate stuff into a new function. That's the elephant in the room in all of these "my language is more readable" discussions, isn't it?
- euccastro 16y agoTo be fair, that's what Lisp's let is syntactic sugar for, too.
- deleted 16y ago[deleted]
- StavrosK 16y agoYes: main_scope_stuff() with create_context() as c: for foo in foos: do_something(foo, c) do_other_thing(foo, c) accumulate(foos, c) more_main_scope_stuff() That signifies that "c" isn't supposed to be available after scope of the "with" statement. The variable will still be bound, but conceptually it's unavailable, since it's not supposed to be used. Also, the object in create_context() needs to support being called like that (i.e. it should contain __enter__ and __exit__ methods).
- euccastro 16y ago> The variable will still be bound, but conceptually it's unavailable, since it's not supposed to be used. Which, in all fairness, is the same as saying that this does not indeed create a new scope. If you're going to rely on convention, you might as well dispense with the 'with' statement at all and use blank lines. An explicit and safe (if not very elegant) way to put a variable out of scope is just deleting it after you're done with it: main_scope_stuff() if True: # Let's say we _really_ want indentation here.. c = create_context() for foo in foos: do_something(foo, c) do_other_thing(foo, c) accumulate(foos, c) del c # something_or_other(c) <--- raises UnboundLocalError more_main_scope_stuff() That said, if it got to the point of going to this trouble I'd just make a nested function instead.
- neutronicus 16y agoThat's nice, I didn't know about that, thanks. I'll definitely be using it the next time I have to use Python. It's a little bit unsatisfying, since all of the context has to be wrapped in a single object, but that does cover a common class of Lisp macro use cases.