Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #7635 > unrolled thread
| Started by | Eric Snow <ericsnowcurrently@gmail.com> |
|---|---|
| First post | 2011-06-14 16:28 -0600 |
| Last post | 2011-06-15 10:43 +1000 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.lang.python
break in a module Eric Snow <ericsnowcurrently@gmail.com> - 2011-06-14 16:28 -0600
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-14 16:51 -0700
Re: break in a module Ben Finney <ben+python@benfinney.id.au> - 2011-06-15 10:43 +1000
| From | Eric Snow <ericsnowcurrently@gmail.com> |
|---|---|
| Date | 2011-06-14 16:28 -0600 |
| Subject | break in a module |
| Message-ID | <mailman.237.1308090506.11593.python-list@python.org> |
When you want to stop execution of a statement body early, for flow
control, there is a variety ways you can go, depending on the context.
Loops have break and continue. Functions have return. Generators
have yield (which temporarily stops execution). Exceptions sort of
work for everything, but have to be caught by a surrounding scope, and
are not necessarily meant for general flow control.
Is there a breaking flow control mechanism for modules?
Regardless of the context, I've found it cleaner to use flow control
statements, like break, continue, and return, to stop execution under
some condition and then leave the rest of my code at the smaller
indentation level. For example:
for i in range(5):
if i % 2:
print("odd: %s" % i)
continue
print("even: %s" % i)
This could be written with if-else for control flow:
for i in range(5):
if i % 2:
print("odd: %s" % i)
else:
print("even: %s" % i)
Or, for functions:
def f(arg):
if not arg:
return None
print("found something: %s" % arg)
return arg
vs:
def f(arg):
if not arg:
result = None
else:
print("found something: %s" % arg)
result = arg
return result
The more levels of indentation the harder it becomes to read.
However, with the breaking flow control statements, you can mitigate
the nesting levels somewhat. One nice thing is that when doing this
you can have your default behavior stay at the smallest indentation
level, so the logic is easier to read.
With modules I sometimes have code at the beginning to do some small
task if a certain condition is met, and otherwise execute the rest of
the module body. Here's my main use case:
"""some module"""
import sys
import importlib
import util # some utility module somewhere...
if __name__ == "__main__":
name = util.get_module_name(sys.modules[__name__])
module = importlib.import_module(name)
sys.modules[__name__] = module
else:
# do my normal stuff at 1 indentation level
I would rather have something like this:
"""some module"""
import sys
import importlib
import util # some utility module somewhere...
if __name__ == "__main__":
name = util.get_module_name(sys.modules[__name__])
module = importlib.import_module(name)
sys.modules[__name__] = module
break
# do my normal stuff at 0 indentation level
So, any thoughts? Thanks.
-eric
p.s. I might just handle this with a PEP 302 import hook regardless,
but it would still be nice to know if there is a better solution than
basically indenting my entire module.
[toc] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-14 16:51 -0700 |
| Message-ID | <qaWdnQ6QzelwbmrQnZ2dnUVZ5vidnZ2d@giganews.com> |
| In reply to | #7635 |
Eric Snow wrote:
> With modules I sometimes have code at the beginning to do some small
> task if a certain condition is met, and otherwise execute the rest of
> the module body. Here's my main use case:
>
> """some module"""
>
> import sys
> import importlib
> import util # some utility module somewhere...
>
> if __name__ == "__main__":
> name = util.get_module_name(sys.modules[__name__])
> module = importlib.import_module(name)
> sys.modules[__name__] = module
> else:
> # do my normal stuff at 1 indentation level
>
> I would rather have something like this:
>
> """some module"""
>
> import sys
> import importlib
> import util # some utility module somewhere...
>
> if __name__ == "__main__":
> name = util.get_module_name(sys.modules[__name__])
> module = importlib.import_module(name)
> sys.modules[__name__] = module
> break
>
> # do my normal stuff at 0 indentation level
>
> So, any thoughts? Thanks.
The answer would depend on exactly what "normal stuff" you expect your
module to do if it's not being run as a script (which is what your
`__name__ == '__main__'` check tests for). A typical module will define
it's appropriate attributes, functions, classes, and so on at module
scope. It will then end with a test to see if it's being run as a
script, and then do the appropriate thing. This allows modules to be
imported separately from being executed as scripts.
Your sample code makes it hard to understand the use case, especially
since if you want this hypothetical "module break" to stop executing the
module, then your `__name__ == '__main__'` test basically does nothing
useful (it fiddles with some modules -- especially since it appears to
be they very module that is being executed -- and then quits).
At a more general level, the idea of a "module break" doesn't make much
sense. Modules are just collections of things; they can include some
direct code, but typically consist of mostly definitions. Modules can
interact with each other, be called recursively, etc., and so at an
arbitrary point saying, "break out of this module" doesn't have a great
deal of meaning.
--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM/Y!M/Skype erikmaxfrancis
There is _never_ no hope left. Remember.
-- Louis Wu
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2011-06-15 10:43 +1000 |
| Message-ID | <87wrgnsz47.fsf@benfinney.id.au> |
| In reply to | #7635 |
Eric Snow <ericsnowcurrently@gmail.com> writes: > When you want to stop execution of a statement body early, for flow > control, there is a variety ways you can go, depending on the context. > Loops have break and continue. Functions have return. Generators > have yield (which temporarily stops execution). Exceptions sort of > work for everything, but have to be caught by a surrounding scope, and > are not necessarily meant for general flow control. > > Is there a breaking flow control mechanism for modules? Since your nominated use case is only to do it when ‘__name__ == '__main__'’, you could call ‘sys.exit()’. > With modules I sometimes have code at the beginning to do some small > task if a certain condition is met, and otherwise execute the rest of > the module body. I don't see how your use case needs to skip executing the rest of the module code. > Here's my main use case: > > """some module""" > > import sys > import importlib > import util # some utility module somewhere... > > if __name__ == "__main__": > name = util.get_module_name(sys.modules[__name__]) > module = importlib.import_module(name) > sys.modules[__name__] = module > else: > # do my normal stuff at 1 indentation level What “normal stuff” is the module doing that shouldn't be done when the module is ‘__main__’? I can't see what the use case is for. As you're no doubt aware, the normal pattern is to execute all the “normal stuff” for a module unconditionally, which creates all the objects in the module namespace (its imports, classes, functions, and other attributes) without side effects; then check if the module is ‘__main__’ at the *end*. So you'll probably need to be more specific about why your use case differs from that. -- \ “Pinky, are you pondering what I'm pondering?” “I think so, | `\ Brain, but if the plural of mouse is mice, wouldn't the plural | _o__) of spouse be spice?” —_Pinky and The Brain_ | Ben Finney
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web