while 1 vs while True

T

Timothy Fitz

[ http://www.python.org/moin/PythonSpeed ]
"Starting with Py2.3, the interpreter optimizes 'while 1' to just a
single jump. In contrast "while True" takes several more steps. While
the latter is preferred for clarity, time-critical code should use the
first form."

Out of pure curiousity,
Why wasn't 'While True' optimized also?
 
D

Dan Bishop

Timothy said:
[ http://www.python.org/moin/PythonSpeed ]
"Starting with Py2.3, the interpreter optimizes 'while 1' to just a
single jump. In contrast "while True" takes several more steps. While
the latter is preferred for clarity, time-critical code should use the
first form."

Out of pure curiousity,
Why wasn't 'While True' optimized also?

Probably has something to do with "True" and "False" not being
constants.
.... print 'Not an infinite loop. In fact, it never executes at all.'
 
N

Nick Coghlan

Dan said:
Probably has something to do with "True" and "False" not being
constants.

Yup. Even 'None' only just became a constant in 2.4.

I don't know if 'True' and 'False' are in line for similar treatment (there are
obvious backwards compatibility issues in doing so).

Cheers,
Nick.
 
R

Raymond Hettinger

[Nick Coghlan]
Yup. Even 'None' only just became a constant in 2.4.

I don't know if 'True' and 'False' are in line for similar treatment (there are
obvious backwards compatibility issues in doing so).

It is unlike to before Py3.0. Making them constants would break the reams of
compatability code: True, False = (1==1), (1!=1).


Raymond Hettinger
 
P

Paul Rubin

Raymond Hettinger said:
It is unlike to before Py3.0. Making them constants would break the
reams of compatability code: True, False = (1==1), (1!=1).

I don't see why that particular statement needs to fail. The
interpreter could permit assigning True=True or False=False without
raising an error. Then True and False wouldn't really be constants,
but they'd instead be variables whose value was always known to the
compiler, which for optimization purposes is just as good. The
compiler could alternatively do some simple dataflow analysis to make
sure the values of True and False haven't been changed in a particular
module, before doing that particular optimization.
 
N

Nick Coghlan

Paul said:
I don't see why that particular statement needs to fail. The
interpreter could permit assigning True=True or False=False without
raising an error. Then True and False wouldn't really be constants,
but they'd instead be variables whose value was always known to the
compiler, which for optimization purposes is just as good. The
compiler could alternatively do some simple dataflow analysis to make
sure the values of True and False haven't been changed in a particular
module, before doing that particular optimization.

Until this code:

..>>> import pdb
..>>> pdb.True = 0
..>>> pdb.x = "Darn writeable module dictionaries"
..>>> from pdb import True
..>>> True
0
..>>> from pdb import x
..>>> x
'Darn writeable module dictionaries'


is illegal, the compiler is really limited in what it can safely assume about
the contents of module dictionaries. There's such a thing as being *too*
flexible - and in this case, the flexibility eliminates some potential
optimisations (in this case, "I know what this is" compile time name binding).

I believe modifying a module's globals dictionary from outside the module is in
the process of being deprecated - the catch is that distinguishing it from some
legitimate accesses to a module's globals is not straightforward.

Cheers,
Nick.
 
P

Paul Rubin

Nick Coghlan said:
Until this code:

.>>> import pdb
.>>> pdb.True = 0
.>>> pdb.x = "Darn writeable module dictionaries"
.>>> from pdb import True
.>>> True
0
.>>> from pdb import x
.>>> x
'Darn writeable module dictionaries'

If Python really does behave that way, that bug should be fixed immediately.
 
S

Steve Holden

Raymond said:
[Nick Coghlan]
Yup. Even 'None' only just became a constant in 2.4.

I don't know if 'True' and 'False' are in line for similar treatment (there
are

obvious backwards compatibility issues in doing so).


It is unlike to before Py3.0. Making them constants would break the reams of
compatability code: True, False = (1==1), (1!=1).
It was unfortunate that so many people chose to use that for
compatibility, when if they'd used the same code that the win32all
extensions did they could have retained backward compatibility even
across a change to constants:

try:
True
except AttributeError:
True, False = (1==1), (1!=1)

regards
Steve
 
F

Fredrik Lundh

Steve said:
It was unfortunate that so many people chose to use that for compatibility, when if they'd used
the same code that the win32all extensions did they could have retained backward compatibility
even across a change to constants:

try:
True
except AttributeError:
True, False = (1==1), (1!=1)

that doesn't work, though:

$ python2.1 test.py
Traceback (most recent call last):
File "test.py", line 2, in ?
True
NameError: name 'True' is not defined

</F>
 
P

Peter Otten

Fredrik said:
that doesn't work, though:

$ python2.1 test.py
Traceback (most recent call last):
File "test.py", line 2, in ?
True
NameError: name 'True' is not defined


Fixing the exception type doesn't help if the change is implemented like the
constancy of None:
.... None
.... except NameError:
.... None = object()
....
SyntaxError: assignment to None

Another workaround seems viable:
globals()["None"] = "Evil Nun"
None

Peter
 
S

Steve Holden

Fredrik said:
Steve Holden wrote:




that doesn't work, though:

$ python2.1 test.py
Traceback (most recent call last):
File "test.py", line 2, in ?
True
NameError: name 'True' is not defined
Well, OK. But, lest people should think the worse of win32all because of
my laziness in not finding the exact quote, I should point out that the
code I meant to quote actually says:

# Pre 2.2.1 compat.
try: True, False
except NameError: True = 1==1; False = 1==0

I believe this should work for all versions up to 2.4, and would also
work with a 2.5 that made True and False constants. But if anyone can
prove me wrong it would be you ... :)

regards
Steve
 
S

Steve Holden

Peter said:
Fredrik Lundh wrote:





Fixing the exception type doesn't help if the change is implemented like the
constancy of None:



.... None
.... except NameError:
.... None = object()
....
SyntaxError: assignment to None
Aargghh, so the knowledge of None's constancy appears to extend into the
syntax analysis. Damn, that means my last posting was wrong as well.
Should have checked this all out in 2.4 before asserting things that
weren't true, I suppose.

Interestingly the same error occurs even when attempting sideways access:

Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.SyntaxError: assignment to None

I'm not sure that I actually agree with the classification of this as a
syntax error - there's actually nothing wrong with the syntax at all in
either of these two cases.
Another workaround seems viable:

globals()["None"] = "Evil Nun"
None

Clearly the behavior of None has been fairly radically altered if you
can't see a None in globals any more:

Python 2.3.4 (#53, Oct 18 2004, 20:35:07) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> globals()["None"] = "An Evil String"
>>> None
'An Evil String'

Of course this is all in line with the intention that programmatic
references to None should always pick up the singleton instance of type
NoneType.

It's also quite interesting that the Python 2.4 documentation actually
says (in section 2.5 of the Python Library reference" that False and
True are constants, when they clearly aren't "as constant as None":

Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
regards
Steve
 
S

Steven Bethard

Steve said:
Interestingly the same error occurs even when attempting sideways access:

Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.SyntaxError: assignment to None

And in assignment to something that just looks like it could be None:
.... def __init__(self):
.... self.None = None
Traceback ( File "<interactive input>", line 3
SyntaxError: assignment to None (<interactive input>, line 3)

Another Steve
 
S

Steven Bethard

Steve said:
# Pre 2.2.1 compat.
try: True, False
except NameError: True = 1==1; False = 1==0

I believe this should work for all versions up to 2.4, and would also
work with a 2.5 that made True and False constants. But if anyone can
prove me wrong it would be you ... :)

Seems like it might work, though we couldn't have the SyntaxError like
we do for None:
.... None
.... except NameError:
.... None = 0
Traceback (SyntaxError: assignment to None

Note that even though I don't actually enter the except block, I still
get a SyntaxError.

Another Steve
 
N

Nick Coghlan

Paul said:
If Python really does behave that way, that bug should be fixed immediately.

I tried it out in the 2.4 interpreter before posting it - it certainly does
behave that way.

And some test frameworks do make use of the capability to inject behaviour into
the module under test (e.g. the one mentioned here:
http://mail.python.org/pipermail/python-list/2003-April/156301.html).

This is behaviour which has been around for a while - and breaking such expected
behaviour gratuitously isn't acceptable.

PEP 267 discusses a way of speeding access to globals/builtins without giving up
the external binding of names.

Cheers,
Nick.
 
P

Peter Hansen

Paul said:
If Python really does behave that way, that bug should be fixed immediately.

(My ISP's news server seems to be dropping messages, so I didn't
see Nick's original message above, nor perhaps the message he
was replying to. I hope that doesn't matter to my reply...)

Paul, what is wrong with the above behaviour, that you believe it
to indicate a bug?

As Nick showed in his following reply, there are certainly
people who make use of this behaviour, and I don't believe
it could be duplicated with any other existing feature of
Python. Removing it would, for but one example, cripple
my ability to do effective automated testing in my field
of work.

-Peter
 
T

Terry Reedy

If Python really does behave that way, that bug should be fixed
immediately.

The fact that the attributes of Python modules, like those of classes (and
functions and instances) are externally mutable is a design feature, not a
bug. (Call Python's dynamicity a design bug if you will, but that is
different from a plain 'bug'.)

This allows, for instance, programs to have an in-memory blackboard module
with across-module variables that all other modules can write to as well as
read. This design has been recommended several times on this list. We
would, of course, all agree that having modules arbitrarily poking each
others attributes is a bad idea. Indeed, that is the rationale for
isolating all such pokes into a single blackboard module.

Terry J. Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top