Apply Mark's latest changes to PEP 505
This commit is contained in:
parent
0bc5287a60
commit
23a9ad5cc1
81
pep-0505.txt
81
pep-0505.txt
|
@ -229,12 +229,16 @@ For inexperienced developers, the problem is worse. The top Google hit for
|
||||||
<http://stackoverflow.com/questions/4978738/is-there-a-python-equivalent-of-
|
<http://stackoverflow.com/questions/4978738/is-there-a-python-equivalent-of-
|
||||||
the-c-sharp-null-coalescing-operator>`_, and the top answer says to use ``or``.
|
the-c-sharp-null-coalescing-operator>`_, and the top answer says to use ``or``.
|
||||||
The top answer goes on to explain the caveats of using ``or`` like this, but how
|
The top answer goes on to explain the caveats of using ``or`` like this, but how
|
||||||
many beginning developers go on to read all those caveats?
|
many beginning developers go on to read all those caveats? The accepted answer
|
||||||
|
on `a more recent question <http://stackoverflow.com/questions/13710631/is-
|
||||||
|
there-shorthand-for-returning-a -default-value-if-none-in-python>`_ says to use
|
||||||
|
``or`` without any caveats at all. These two questions have a combined 26,000
|
||||||
|
views!
|
||||||
|
|
||||||
The common usage of ``or`` for the purpose of providing default values is
|
The common usage of ``or`` for the purpose of providing default values is
|
||||||
undeniable, and yet it is also booby-trapped for unsuspecting newcomers. This
|
undeniable, and yet it is also booby-trapped for unsuspecting newcomers. This
|
||||||
suggests that a safe operator for providing default values would have positive
|
suggests that a safe operator for providing default values would have positive
|
||||||
utility. While some critics claim that ``None-aware`` operators will be abused
|
utility. While some critics claim that ``None``-aware operators will be abused
|
||||||
for error handling, they are no more prone to abuse than ``or`` is.
|
for error handling, they are no more prone to abuse than ``or`` is.
|
||||||
|
|
||||||
|
|
||||||
|
@ -773,36 +777,44 @@ Note in the last example that ``time.sleep(10)`` represents an expensive
|
||||||
function call, e.g. initializing a complex data structure. In this example
|
function call, e.g. initializing a complex data structure. In this example
|
||||||
``time.sleep`` is not evaluated, and the result ``300`` is returned instantly.
|
``time.sleep`` is not evaluated, and the result ``300`` is returned instantly.
|
||||||
|
|
||||||
The operator has precedence lower than ``not`` but higher than ``and`` and
|
The operator has higher precedence than the comparison operators ``==``, ``>``,
|
||||||
``or``. This precedence makes reasoning about the order of operations
|
``is``, etc., but lower precedence than any bitwise or arithmetic operators.
|
||||||
comfortable, because it has precedence similar to the operators used for
|
This precedence is chosen for making "default value" expressions intuitive to
|
||||||
coalescing false-y values. Here are pairs of examples, where each item in the
|
read and write::
|
||||||
pair is evaluated identically to the other item in the pair::
|
|
||||||
|
|
||||||
>>> not None ✊🍆 False
|
>>> user_flag = None
|
||||||
True
|
>>> default_flag = True
|
||||||
>>> (not None) ✊🍆 False
|
>>> not user_flag ✊🍆 default_flag # Same as next expression.
|
||||||
|
False
|
||||||
|
>>> not (user_flag ✊🍆 default_flag) # Same as previous.
|
||||||
|
False
|
||||||
|
>>> (not user_flag) ✊🍆 default_flag # Different from previous.
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> 'foo' in dict() ✊🍆 {'foo': 'bar'}
|
>>> user_quantity = None
|
||||||
False
|
>>> default_quantity = 1
|
||||||
>>> ('foo' in dict()) ✊🍆 {'foo': 'bar'}
|
>>> 1 == user_quantity ✊🍆 default_quantity # Same as next expression.
|
||||||
|
True
|
||||||
|
>>> 1 == (user_quantity ✊🍆 default_quantity) # Same as previous.
|
||||||
|
True
|
||||||
|
>>> (1 == user_quantity) ✊🍆 default_quantity # Different from previous.
|
||||||
False
|
False
|
||||||
|
|
||||||
>>> 1 == None ✊🍆 1
|
>>> user_words = None
|
||||||
False
|
>>> default_words = ['foo', 'bar']
|
||||||
>>> (1 == None) ✊🍆 1
|
>>> 'foo' in user_words ✊🍆 default_words # Same as next expression.
|
||||||
False
|
True
|
||||||
|
>>> 'foo' in (user_words ✊🍆 default_words) # Same as previous.
|
||||||
But ``and`` and ``or`` have lower precedence::
|
True
|
||||||
|
>>> ('foo' in user_words) ✊🍆 default_words # Different from previous.
|
||||||
>>> 2 or None ✊🍆 err()
|
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
File "<stdin>", line 1, in <module>
|
File "<stdin>", line 1, in <module>
|
||||||
File "<stdin>", line 1, in err
|
TypeError: argument of type 'NoneType' is not iterable
|
||||||
Exception: foo
|
|
||||||
>>> (2 or None) ✊🍆 err()
|
>>> user_discount = None
|
||||||
2
|
>>> default_discount = 0.9
|
||||||
|
>>> price = 100
|
||||||
|
>>> price * user_discount ✊🍆 default_discount
|
||||||
|
|
||||||
Recall the example above of calculating the cost of items in a shopping cart,
|
Recall the example above of calculating the cost of items in a shopping cart,
|
||||||
and the easy-to-miss bug. This type of bug is not possible with the ``None``-
|
and the easy-to-miss bug. This type of bug is not possible with the ``None``-
|
||||||
|
@ -840,9 +852,8 @@ preserving the short circuit semantics of the code that it replaces.
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
The idea of a ``None``-aware function invocation syntax was discussed on python-
|
The idea of a ``None``-aware function invocation syntax was discussed on python-
|
||||||
ideas, but the idea was rejected by BDFL. The reasons for this rejection are
|
ideas. The idea was not popular, so no such operator is included in this
|
||||||
detailed above.
|
proposal. (Justification for its exclusion is discussed in a previous section.)
|
||||||
|
|
||||||
Still, calling a function when it is not ``None`` is a common idiom in Python,
|
Still, calling a function when it is not ``None`` is a common idiom in Python,
|
||||||
particularly for callback functions. Consider this hypothetical example::
|
particularly for callback functions. Consider this hypothetical example::
|
||||||
|
|
||||||
|
@ -865,10 +876,11 @@ written more concisely as::
|
||||||
|
|
||||||
Instead, consider a "``None``-severing" operator, however, which is a short-
|
Instead, consider a "``None``-severing" operator, however, which is a short-
|
||||||
circuiting, boolean operator similar to the ``None``-coalesing operator, except
|
circuiting, boolean operator similar to the ``None``-coalesing operator, except
|
||||||
it returns its left operand if that operand is None and otherwise returns the
|
it returns ``None`` if the left operand is ``None`` and returns the right
|
||||||
right operand. If the left operand is None, then the right operand is not
|
operand otherwise. It has short circuiting behavior that compliments the
|
||||||
evaluated. Let's temporarily spell this operator ``✂`` and rewrite the example
|
``None``-coalescing operator: if the left operand is None, then the right
|
||||||
accordingly::
|
operand is not evaluated. Let's temporarily spell this operator ``✂`` and
|
||||||
|
rewrite the example accordingly::
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -1153,7 +1165,7 @@ operator.
|
||||||
2. ``foo or? bar or? baz``
|
2. ``foo or? bar or? baz``
|
||||||
- Pros: similar to existing ``or`` operator
|
- Pros: similar to existing ``or`` operator
|
||||||
- Cons: the difference between this and ``or`` is not intuitive; punctuation
|
- Cons: the difference between this and ``or`` is not intuitive; punctuation
|
||||||
is ugly
|
is ugly; different precedence from ``or`` may be confusing
|
||||||
3. ``foo ? bar ? baz``
|
3. ``foo ? bar ? baz``
|
||||||
- Pros: similar to ``??`` used in other languages
|
- Pros: similar to ``??`` used in other languages
|
||||||
- Cons: punctuation is ugly; possible conflict with IPython; not used by any
|
- Cons: punctuation is ugly; possible conflict with IPython; not used by any
|
||||||
|
@ -1189,7 +1201,8 @@ the ``None``- coalescing operator.
|
||||||
2. ``foo and? bar``
|
2. ``foo and? bar``
|
||||||
- Pros: symmetric with ``or?``
|
- Pros: symmetric with ``or?``
|
||||||
- Cons: punctuation is ugly; possible conflict with IPython; difficult to
|
- Cons: punctuation is ugly; possible conflict with IPython; difficult to
|
||||||
google to find out what it means
|
google to find out what it means; different precedence from ``and`` may be
|
||||||
|
confusing
|
||||||
3. No ``None``-severing operator.
|
3. No ``None``-severing operator.
|
||||||
- (Pros and cons discussed throughout this document.)
|
- (Pros and cons discussed throughout this document.)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue