Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #7643 > unrolled thread
| Started by | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| First post | 2011-06-14 16:28 -0700 |
| Last post | 2011-06-15 11:33 +1000 |
| Articles | 20 on this page of 35 — 9 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: break in a module Ethan Furman <ethan@stoneleaf.us> - 2011-06-14 16:28 -0700
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-14 16:51 -0700
Re: break in a module Eric Snow <ericsnowcurrently@gmail.com> - 2011-06-14 18:51 -0600
Re: break in a module Ben Finney <ben+python@benfinney.id.au> - 2011-06-15 11:33 +1000
Re: break in a module Eric Snow <ericsnowcurrently@gmail.com> - 2011-06-14 20:21 -0600
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 15:09 -0700
Re: break in a module Dave Angel <davea@ieee.org> - 2011-06-15 00:02 -0400
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 15:07 -0700
Re: break in a module Chris Angelico <rosuav@gmail.com> - 2011-06-17 09:27 +1000
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 16:29 -0700
Re: break in a module Eric Snow <ericsnowcurrently@gmail.com> - 2011-06-16 18:00 -0600
Re: break in a module Chris Angelico <rosuav@gmail.com> - 2011-06-17 10:01 +1000
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 18:13 -0700
Re: break in a module Ethan Furman <ethan@stoneleaf.us> - 2011-06-16 19:17 -0700
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 21:21 -0700
Re: break in a module Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-16 22:53 -0600
Re: break in a module Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-17 00:48 +0000
Re: break in a module Chris Angelico <rosuav@gmail.com> - 2011-06-17 10:57 +1000
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 18:21 -0700
Re: break in a module Ethan Furman <ethan@stoneleaf.us> - 2011-06-16 19:11 -0700
Re: break in a module Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-16 19:58 -0600
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 21:24 -0700
Re: break in a module Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-16 22:50 -0600
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-16 22:20 -0700
Re: break in a module Chris Angelico <rosuav@gmail.com> - 2011-06-17 15:56 +1000
Re: break in a module Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-17 06:00 +0000
Re: break in a module Erik Max Francis <max@alcyone.com> - 2011-06-17 00:09 -0700
Re: break in a module Cameron Simpson <cs@zip.com.au> - 2011-06-18 12:36 +1000
Re: break in a module Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-18 03:50 +0000
Re: break in a module Chris Angelico <rosuav@gmail.com> - 2011-06-18 14:31 +1000
Re: break in a module Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-18 04:49 +0000
Re: break in a module Chris Angelico <rosuav@gmail.com> - 2011-06-18 15:06 +1000
Re: break in a module Cameron Simpson <cs@zip.com.au> - 2011-06-21 20:04 +1000
Re: break in a module Eric Snow <ericsnowcurrently@gmail.com> - 2011-06-17 00:25 -0600
Re: break in a module Chris Angelico <rosuav@gmail.com> - 2011-06-15 11:33 +1000
Page 1 of 2 [1] 2 Next page →
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2011-06-14 16:28 -0700 |
| Subject | Re: break in a module |
| Message-ID | <mailman.240.1308093309.11593.python-list@python.org> |
MRAB wrote:
> On 14/06/2011 23:28, Eric Snow wrote:
>> 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.
>>
> To me, the obvious choice would be "return", not "break".
To me, too -- too bad it doesn't work:
c:\temp>\python32\python early_abort.py
File "early_abort.py", line 7
return
^
SyntaxError: 'return' outside function
~Ethan~
[toc] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-14 16:51 -0700 |
| Message-ID | <qaWdnQmQzemLaWrQnZ2dnUVZ5vidnZ2d@giganews.com> |
| In reply to | #7643 |
Ethan Furman wrote:
> MRAB wrote:
>> On 14/06/2011 23:28, Eric Snow wrote:
>>> 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.
>>>
>> To me, the obvious choice would be "return", not "break".
>
> To me, too -- too bad it doesn't work:
>
> c:\temp>\python32\python early_abort.py
> File "early_abort.py", line 7
> return
> ^
> SyntaxError: 'return' outside function
Nor should it. There's nothing to return out of.
--
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 | Eric Snow <ericsnowcurrently@gmail.com> |
|---|---|
| Date | 2011-06-14 18:51 -0600 |
| Message-ID | <mailman.247.1308099095.11593.python-list@python.org> |
| In reply to | #7647 |
On Tue, Jun 14, 2011 at 5:51 PM, Erik Max Francis <max@alcyone.com> wrote:
> Ethan Furman wrote:
>>
>> To me, too -- too bad it doesn't work:
>>
>> c:\temp>\python32\python early_abort.py
>> File "early_abort.py", line 7
>> return
>> ^
>> SyntaxError: 'return' outside function
>
> Nor should it. There's nothing to return out of.
>
Perhaps we have a misunderstanding then. The contents of a module
file are the body of the module definition. Like the body of any
other complex statement, that body is going to get executed [1].
Some of the complex statements have keywords that let you break out of
that execution, like break and continue in loops. Some do not.
However, there is most certainly something out of which to return, the
execution of the module body.
That fact that the functionality is not there does not mean it has to
stay that way. It may just be that no one has thought to add it. I
don't agree that it's a bad idea. I have a use case. The alternative
is unappealing to me. That's how new features are born.
I apologize if my example was unclear. I kept it pretty simple. I
expect using __main__ was misleading. However, this is by no means
the only use case. In general it would be nice to do some checks up
front and decide whether or not to continue executing the module,
rather than waiting until the end to decide:
if condition_1:
...
return
if condition_2:
...
return
# now do my expensive module stuff
# finally handle being run as a script
if __name__ == "__main__":
...
The only ways that I know of to accomplish this currently is either by
putting everything inside if-else blocks, or raise some kind of
ImportBreak exception and catch it in an import hook. I would rather
not use either one. The more levels of indentation in a module, the
harder it is to follow. And exceptions really should not be involved
in execution flow control, but in the handling of abnormal situations
instead.
Considering that other complex statements have special flow control
statements, I don't see why modules shouldn't either.
-eric
[1] During import the module gets compiled and the result is exec'ed
in the context of the __dict__ of a new ModuleType object. That
module object is then placed in sys.modules and bound to the name you
have in the import statement in the module from which you issued that
statement. Remember, the module is executed once, when the import
statement is executed. That is when the module flow control would
happen.
> --
> 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
> --
> http://mail.python.org/mailman/listinfo/python-list
>
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2011-06-15 11:33 +1000 |
| Message-ID | <87k4cnswt9.fsf@benfinney.id.au> |
| In reply to | #7657 |
Eric Snow <ericsnowcurrently@gmail.com> writes: > I apologize if my example was unclear. I kept it pretty simple. That's a good goal, but unfortunately in this case it means the purpose is opaque. > In general it would be nice to do some checks up front and decide > whether or not to continue executing the module, rather than waiting > until the end to decide: > > if condition_1: > ... > return > if condition_2: > ... > return > > # now do my expensive module stuff I have never seen code that needs this, and can't imagine why the above would be a good design for a module. Is there real code online somewhere that we can see which serves as a real example for your use case? -- \ “There is no reason anyone would want a computer in their | `\ home.” —Ken Olson, president, chairman and founder of Digital | _o__) Equipment Corp., 1977 | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Eric Snow <ericsnowcurrently@gmail.com> |
|---|---|
| Date | 2011-06-14 20:21 -0600 |
| Message-ID | <mailman.251.1308104514.11593.python-list@python.org> |
| In reply to | #7661 |
On Tue, Jun 14, 2011 at 7:33 PM, Ben Finney <ben+python@benfinney.id.au> wrote: > > I have never seen code that needs this, and can't imagine why the above > would be a good design for a module. Is there real code online somewhere > that we can see which serves as a real example for your use case? > Unfortunately not. Most of this line of thinking is the result of looking at import functionality in different ways, including with regards to the problem of modules getting imported twice (once as __main__). I've been doing work on multi-file modules, custom module objects, and custom import hooks lately, so I have been exploring a lot of the import related features. The situation came up where I was trying to actually apply some of that across a large package. The use case I originally gave is the real-life one that got me thinking about module flow control statements. However, the situation that led me there is not particularly wide-spread. Keep in mind that initially I was looking to see if there was something like return or break for modules, and not asking that they be added. That "expensive module stuff" example I gave was purely hypothetical, and I haven't really seen real code like it either. Like I said, my main motivation is to reduce my levels of indentation somewhat. I was trying to see if I could apply a pattern I use in functions and loops to modules. Things like "I have never seen..." are really helpful to hear, by the way, so thanks! -eric > -- > \ “There is no reason anyone would want a computer in their | > `\ home.” —Ken Olson, president, chairman and founder of Digital | > _o__) Equipment Corp., 1977 | > Ben Finney > -- > http://mail.python.org/mailman/listinfo/python-list >
[toc] | [prev] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-16 15:09 -0700 |
| Message-ID | <6NWdnfNF0riS4mfQnZ2dnUVZ5h2dnZ2d@giganews.com> |
| In reply to | #7665 |
Eric Snow wrote:
> Like I said, my main motivation is to reduce my levels of indentation
> somewhat. I was trying to see if I could apply a pattern I use in
> functions and loops to modules.
If your sole goal here is to reduce clutter, then turn a repeated
if/elif/else case into a dictionary lookup where the keys are functions,
and execute the value. Even then, unless there are quite a lot of
cases, this may be overkill.
--
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
I am not afraid / To be a lone Bohemian
-- Lamya
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@ieee.org> |
|---|---|
| Date | 2011-06-15 00:02 -0400 |
| Message-ID | <mailman.253.1308110548.11593.python-list@python.org> |
| In reply to | #7661 |
On 01/-10/-28163 02:59 PM, Eric Snow wrote: > <snip> > > Unfortunately not. Most of this line of thinking is the result of > looking at import functionality in different ways, including with > regards to the problem of modules getting imported twice (once as > __main__). I've been doing work on multi-file modules, custom module Watch out for that importing of the original script. Doing that has many risks, only one of which is the problem of the two names. In fact, any time you have mutual imports, you run a certain risk, if the modules involved have any code that's not inside defs. It's not well defined what order the initialisation happens, so you may wind up calling code in another module that's not really there yet. The module import tree should be strictly hierarchical, without cycles. if you need stuff from the __main__, pass it to the other module, don't let the other module peek back over your shoulder. In the case of a module importing things from your script, the solution is pretty simple. Move the needed code elsewhere, and import it both from your script and from the other module. DaveA
[toc] | [prev] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-16 15:07 -0700 |
| Message-ID | <6NWdnfBF0rgB42fQnZ2dnUVZ5h2dnZ2d@giganews.com> |
| In reply to | #7657 |
Eric Snow wrote:
> On Tue, Jun 14, 2011 at 5:51 PM, Erik Max Francis <max@alcyone.com> wrote:
>> Ethan Furman wrote:
>>> To me, too -- too bad it doesn't work:
>>>
>>> c:\temp>\python32\python early_abort.py
>>> File "early_abort.py", line 7
>>> return
>>> ^
>>> SyntaxError: 'return' outside function
>> Nor should it. There's nothing to return out of.
>
> Perhaps we have a misunderstanding then. The contents of a module
> file are the body of the module definition. Like the body of any
> other complex statement, that body is going to get executed [1].
>
> Some of the complex statements have keywords that let you break out of
> that execution, like break and continue in loops. Some do not.
It's quite consistent on which control structures you can break out of
-- it's the looping ones.
> However, there is most certainly something out of which to return, the
> execution of the module body.
You return out of functions or methods. Not modules.
> I apologize if my example was unclear. I kept it pretty simple. I
> expect using __main__ was misleading. However, this is by no means
> the only use case. In general it would be nice to do some checks up
> front and decide whether or not to continue executing the module,
> rather than waiting until the end to decide:
>
> if condition_1:
> ...
> return
> if condition_2:
> ...
> return
>
> # now do my expensive module stuff
>
> # finally handle being run as a script
> if __name__ == "__main__":
> ...
>
> The only ways that I know of to accomplish this currently is either by
> putting everything inside if-else blocks, or raise some kind of
> ImportBreak exception and catch it in an import hook.
You're still not elucidating a very clear use case here. You want to do
some tests and then break out of the top-level execution of the module
if they happen. Just use `sys.exit`.
It's still not clear _why_ this is useful. As I said, the typical
behavior of a module is to define a lot of things, perhaps building up
some needed data structures, and then do the `__name__ == "__main__"`
test to see if it's being executed as a script, and then _do_ something.
So it's still not clear what tests you're trying to perform while
defining the contents of the module (but before executing it as a
script, should that be the case), and then exit.
The only situation where the execution of the contents of the module
might vary with top-level branching tests is for portability or version
reasons, say, checking `sys.platform` or `sys.version` and then doing
different things depending on their values. But these are easily
handled with if/else structures -- or, if that gets unwieldy, using a
lookup table -- and, at any rate, you're _not_ going to "break out of
the module" once you've done that, you're going to continue on
definition the non-(platform, version)-specific stuff, then test whether
it's being run as a script, and then do something.
The only case I can see for exiting out of a module early would be if
something exceptional happens that leads the module's internal logic to
conclude that it can't be used. But the solution there is
straightforward: Raise an exception.
--
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
We have always been space travelers.
-- Carl Sagan, 1934-1996
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-06-17 09:27 +1000 |
| Message-ID | <mailman.45.1308266847.1164.python-list@python.org> |
| In reply to | #7770 |
On Fri, Jun 17, 2011 at 8:07 AM, Erik Max Francis <max@alcyone.com> wrote: > It's quite consistent on which control structures you can break out of -- > it's the looping ones. Plus functions. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-16 16:29 -0700 |
| Message-ID | <VoednYBJ64pgDGfQnZ2dnUVZ5vCdnZ2d@giganews.com> |
| In reply to | #7775 |
Chris Angelico wrote:
> On Fri, Jun 17, 2011 at 8:07 AM, Erik Max Francis <max@alcyone.com> wrote:
>> It's quite consistent on which control structures you can break out of --
>> it's the looping ones.
>
> Plus functions.
No:
>>> def f():
... break
...
File "<stdin>", line 2
SyntaxError: 'break' outside loop
--
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
Do not stand in a place of danger trusting in miracles.
-- (an Arab proverb)
[toc] | [prev] | [next] | [standalone]
| From | Eric Snow <ericsnowcurrently@gmail.com> |
|---|---|
| Date | 2011-06-16 18:00 -0600 |
| Message-ID | <mailman.48.1308268834.1164.python-list@python.org> |
| In reply to | #7776 |
On Thu, Jun 16, 2011 at 5:29 PM, Erik Max Francis <max@alcyone.com> wrote: > Chris Angelico wrote: >> >> On Fri, Jun 17, 2011 at 8:07 AM, Erik Max Francis <max@alcyone.com> wrote: >>> >>> It's quite consistent on which control structures you can break out of -- >>> it's the looping ones. >> >> Plus functions. > > No: > >>>> def f(): > ... break > ... > File "<stdin>", line 2 > SyntaxError: 'break' outside loop > Yeah, I see what you mean. I wasn't talking about the actual break keyword, but rather having a "break" in execution. Basically execution of the current frame stops and returns; loop bodies aren't handled in their own execution frames but effectively it's the same idea. So, a little namespace collision between us there on the words break and return. Regardless, for the only real use case I had for module breaking flow control, I have a better solution anyway. Thanks again for your feedback. -eric > -- > 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 > Do not stand in a place of danger trusting in miracles. > -- (an Arab proverb) > -- > http://mail.python.org/mailman/listinfo/python-list >
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-06-17 10:01 +1000 |
| Message-ID | <mailman.49.1308268903.1164.python-list@python.org> |
| In reply to | #7776 |
On Fri, Jun 17, 2011 at 9:29 AM, Erik Max Francis <max@alcyone.com> wrote:
> Chris Angelico wrote:
>>
>> On Fri, Jun 17, 2011 at 8:07 AM, Erik Max Francis <max@alcyone.com> wrote:
>>>
>>> It's quite consistent on which control structures you can break out of --
>>> it's the looping ones.
>>
>> Plus functions.
>
> No:
>
>>>> def f():
> ... break
> ...
> File "<stdin>", line 2
> SyntaxError: 'break' outside loop
Yes:
def f():
return
print("Won't happen")
"break out of" doesn't necessarily require the break keyword per se.
You can abort a function part way, same as you can abort a loop part
way.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-16 18:13 -0700 |
| Message-ID | <udSdnbrpPMe_N2fQnZ2dnUVZ5hWdnZ2d@giganews.com> |
| In reply to | #7780 |
Chris Angelico wrote:
> On Fri, Jun 17, 2011 at 9:29 AM, Erik Max Francis <max@alcyone.com> wrote:
>> Chris Angelico wrote:
>>> On Fri, Jun 17, 2011 at 8:07 AM, Erik Max Francis <max@alcyone.com> wrote:
>>>> It's quite consistent on which control structures you can break out of --
>>>> it's the looping ones.
>>> Plus functions.
>> No:
>>
>>>>> def f():
>> ... break
>> ...
>> File "<stdin>", line 2
>> SyntaxError: 'break' outside loop
>
> Yes:
> def f():
> return
> print("Won't happen")
>
> "break out of" doesn't necessarily require the break keyword per se.
> You can abort a function part way, same as you can abort a loop part
> way.
Look back at the context. I was actually talking about the break keyword.
--
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
Human salvation lies in the hands of the creatively maladjusted.
-- Dr. Martin Luther King, Jr.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2011-06-16 19:17 -0700 |
| Message-ID | <mailman.57.1308276441.1164.python-list@python.org> |
| In reply to | #7788 |
Erik Max Francis wrote:
> Chris Angelico wrote:
>> On Fri, Jun 17, 2011 at 9:29 AM, Erik Max Francis <max@alcyone.com>
>> wrote:
>>> Chris Angelico wrote:
>>>> On Fri, Jun 17, 2011 at 8:07 AM, Erik Max Francis <max@alcyone.com>
>>>> wrote:
>>>>> It's quite consistent on which control structures you can break out
>>>>> of --
>>>>> it's the looping ones.
>>>> Plus functions.
>>> No:
>>>
>>>>>> def f():
>>> ... break
>>> ...
>>> File "<stdin>", line 2
>>> SyntaxError: 'break' outside loop
>>
>> Yes:
>> def f():
>> return
>> print("Won't happen")
>>
>> "break out of" doesn't necessarily require the break keyword per se.
>> You can abort a function part way, same as you can abort a loop part
>> way.
>
> Look back at the context. I was actually talking about the break keyword.
The Context:
"It's quite consistent on which control structures you can break out of"
Hmmm.... Nope, nothing there to suggest you were talking about the
'break' keyword.
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-16 21:21 -0700 |
| Message-ID | <CuGdnSzkSq7bS2fQnZ2dnUVZ5vudnZ2d@giganews.com> |
| In reply to | #7792 |
Ethan Furman wrote:
> The Context:
>
> "It's quite consistent on which control structures you can break out of"
>
> Hmmm.... Nope, nothing there to suggest you were talking about the
> 'break' keyword.
That's what I wrote, all right, but not its context. I suspect you're
just being difficult.
--
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
Winners are men who have dedicated their whole lives to winning.
-- Woody Hayes
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-06-16 22:53 -0600 |
| Message-ID | <mailman.60.1308286437.1164.python-list@python.org> |
| In reply to | #7795 |
On Thu, Jun 16, 2011 at 10:21 PM, Erik Max Francis <max@alcyone.com> wrote: > Ethan Furman wrote: >> >> The Context: >> >> "It's quite consistent on which control structures you can break out of" >> >> Hmmm.... Nope, nothing there to suggest you were talking about the 'break' >> keyword. > > That's what I wrote, all right, but not its context. I suspect you're just > being difficult. The exact context was: """ Some of the complex statements have keywords that let you break out of that execution, like break and continue in loops. Some do not. """ which is about the breaking keywords in general (break, continue, return), not about break specifically.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-06-17 00:48 +0000 |
| Message-ID | <4dfaa441$0$30002$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #7770 |
On Thu, 16 Jun 2011 15:07:23 -0700, Erik Max Francis wrote:
> Eric Snow wrote:
>>
>> The only ways that I know of to accomplish this currently is either by
>> putting everything inside if-else blocks, or raise some kind of
>> ImportBreak exception and catch it in an import hook.
>
> You're still not elucidating a very clear use case here. You want to do
> some tests and then break out of the top-level execution of the module
> if they happen. Just use `sys.exit`.
>
> It's still not clear _why_ this is useful. As I said, the typical
> behavior of a module is to define a lot of things, perhaps building up
> some needed data structures, and then do the `__name__ == "__main__"`
> test to see if it's being executed as a script, and then _do_ something.
I'm not entirely sure that this is a *good* use case, but I think the use
case that Eric Snow has in mind is something like this pseudo-code:
# === in module other.py which is not the main module ===
def spam(): pass
if some_condition: stop processing
def ham(): pass
def cheese(): pass
def salad(): pass
# === in the main module ===
import other
other.spam() # always defined
try:
other.ham
except AttributeError:
print "there is no ham"
sys.exit would be inappropriate, because the intention is not to exit the
entire application, but just to halt processing of the module. You could
wrap the def cheese inside an if block, but if there's a lot of
conditional code, then the majority of your module might be indented,
which seems silly.
If Python had GOTOs this would be a perfect use-case for jumping to a
label at the end of the file :)
Perhaps the most sensible alternative is conditional importing:
# === module extras.py ===
def ham(): pass
def cheese(): pass
def salad(): pass
# === module other.py ===
def spam(): pass
if not some_condition: from extras import *
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-06-17 10:57 +1000 |
| Message-ID | <mailman.51.1308272276.1164.python-list@python.org> |
| In reply to | #7781 |
On Fri, Jun 17, 2011 at 10:48 AM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > Perhaps the most sensible alternative is conditional importing: > > # === module extras.py === > > def ham(): pass > def cheese(): pass > def salad(): pass > > > # === module other.py === > > def spam(): pass > > if not some_condition: from extras import * > This would, if I understand imports correctly, have ham() operate in one namespace and spam() in another. Depending on what's being done, that could be quite harmless, or it could be annoying (no sharing module-level constants, etc). As to which keyword is used, I would be inclined to go with 'return' rather than 'break'. The module is thus a procedure in its own right. Of course, that's assuming the feature's actually needed, which isn't certain by any means. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Erik Max Francis <max@alcyone.com> |
|---|---|
| Date | 2011-06-16 18:21 -0700 |
| Message-ID | <VOGdnS1-M-W9MWfQnZ2dnUVZ5vSdnZ2d@giganews.com> |
| In reply to | #7784 |
Chris Angelico wrote:
> On Fri, Jun 17, 2011 at 10:48 AM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> Perhaps the most sensible alternative is conditional importing:
>>
>> # === module extras.py ===
>>
>> def ham(): pass
>> def cheese(): pass
>> def salad(): pass
>>
>>
>> # === module other.py ===
>>
>> def spam(): pass
>>
>> if not some_condition: from extras import *
>>
>
> This would, if I understand imports correctly, have ham() operate in
> one namespace and spam() in another. Depending on what's being done,
> that could be quite harmless, or it could be annoying (no sharing
> module-level constants, etc).
No, he's using `from ... import *`. It dumps it all in the same
namespace (which is usually why it's frowned upon, but in his example
it's kind of the point).
I don't see it as a very compelling solution beyond putting code using a
simple `if`. And it's still rather hard to imagine a serious use case.
> As to which keyword is used, I would be inclined to go with 'return'
> rather than 'break'. The module is thus a procedure in its own right.
> Of course, that's assuming the feature's actually needed, which isn't
> certain by any means.
Neither makes sense. `break` exits out of looping structures, which the
top-level code of a module most certainly is not. `return` returns out
of functions or methods and -- most importantly -- _returns something_.
(`return` without an argument returns None). Modules have no facility
to return anything, nor would it make much sense at all to do so.
This is an example of a problem that simply does not need solving with
additional language changes: There are already perfectly good (and,
perhaps more importantly, clear) facilities to do whatever it is you
want to do. If you want to exit, call `sys.exit`. If you want to
conditionally execute some code, use `if`. If you want to indicate an
exceptional condition, raise an exception.
--
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
Human salvation lies in the hands of the creatively maladjusted.
-- Dr. Martin Luther King, Jr.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2011-06-16 19:11 -0700 |
| Message-ID | <mailman.55.1308275880.1164.python-list@python.org> |
| In reply to | #7789 |
Erik Max Francis wrote:
> Chris Angelico wrote:
>> On Fri, Jun 17, 2011 at 10:48 AM, Steven D'Aprano
>> <steve+comp.lang.python@pearwood.info> wrote:
>>> Perhaps the most sensible alternative is conditional importing:
>>>
>>> # === module extras.py ===
>>>
>>> def ham(): pass
>>> def cheese(): pass
>>> def salad(): pass
>>>
>>>
>>> # === module other.py ===
>>>
>>> def spam(): pass
>>>
>>> if not some_condition: from extras import *
>>>
>>
>> This would, if I understand imports correctly, have ham() operate in
>> one namespace and spam() in another. Depending on what's being done,
>> that could be quite harmless, or it could be annoying (no sharing
>> module-level constants, etc).
>
> No, he's using `from ... import *`. It dumps it all in the same
> namespace
Wrong, with a little bit right. The 'from ... *' functions are now
bound in the calling namespace, but they still execute in their original
namespace. Observe:
8<--these.py---------------------------------------------------------
import this
this.yummy()
8<--this.py----------------------------------------------------------
breakfast = 'ham and eggs'
def spam():
print(breakfast)
if 'spam' not in breakfast:
from that import *
8<--that.py----------------------------------------------------------
def yummy():
print(breakfast)
8<--results----------------------------------------------------------
--> import these
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "these.py", line 3, in <module>
this.yummy()
File "that.py", line 2, in yummy
print(breakfast)
NameError: global name 'breakfast' is not defined
8<-------------------------------------------------------------------
~Ethan~
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web