Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #7643 > unrolled thread

Re: break in a module

Started byEthan Furman <ethan@stoneleaf.us>
First post2011-06-14 16:28 -0700
Last post2011-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.


Contents

  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 →


#7643 — Re: break in a module

FromEthan Furman <ethan@stoneleaf.us>
Date2011-06-14 16:28 -0700
SubjectRe: 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]


#7647

FromErik Max Francis <max@alcyone.com>
Date2011-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]


#7657

FromEric Snow <ericsnowcurrently@gmail.com>
Date2011-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]


#7661

FromBen Finney <ben+python@benfinney.id.au>
Date2011-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]


#7665

FromEric Snow <ericsnowcurrently@gmail.com>
Date2011-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]


#7771

FromErik Max Francis <max@alcyone.com>
Date2011-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]


#7668

FromDave Angel <davea@ieee.org>
Date2011-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]


#7770

FromErik Max Francis <max@alcyone.com>
Date2011-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]


#7775

FromChris Angelico <rosuav@gmail.com>
Date2011-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]


#7776

FromErik Max Francis <max@alcyone.com>
Date2011-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]


#7779

FromEric Snow <ericsnowcurrently@gmail.com>
Date2011-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]


#7780

FromChris Angelico <rosuav@gmail.com>
Date2011-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]


#7788

FromErik Max Francis <max@alcyone.com>
Date2011-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]


#7792

FromEthan Furman <ethan@stoneleaf.us>
Date2011-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]


#7795

FromErik Max Francis <max@alcyone.com>
Date2011-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]


#7799

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-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]


#7781

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-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]


#7784

FromChris Angelico <rosuav@gmail.com>
Date2011-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]


#7789

FromErik Max Francis <max@alcyone.com>
Date2011-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]


#7790

FromEthan Furman <ethan@stoneleaf.us>
Date2011-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