Add PEP 572 examples from stdlib (#698)

This commit is contained in:
Guido van Rossum 2018-07-07 14:05:56 -07:00 committed by GitHub
parent e89685036f
commit 23a91023fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 126 additions and 5 deletions

View File

@ -359,6 +359,127 @@ found in assignment statements:
Examples Examples
======== ========
Examples from the Python standard library
-----------------------------------------
site.py
^^^^^^^
+-----------------------------------------------------+------------------------------------------------------------+
| Current code | Replaced with |
+-----------------------------------------------------+------------------------------------------------------------+
| | |
| :: | :: |
| | |
| env_base = os.environ.get("PYTHONUSERBASE", None) | if env_base := os.environ.get("PYTHONUSERBASE", None): |
| if env_base: | return env_base |
| return env_base | |
| | |
+-----------------------------------------------------+------------------------------------------------------------+
*env_base* is only used on these lines, putting its assignment on the if
moves it as the "header" of the block.
_pydecimal.py
^^^^^^^^^^^^^
+----------------------------------------------+-----------------------------------------------------------------------+
| Current code | Replaced with |
+----------------------------------------------+-----------------------------------------------------------------------+
| | |
| :: | :: |
| | |
| if self._is_special: | if self._is_special and (ans := self._check_nans(context=context)): |
| ans = self._check_nans(context=context) | return ans |
| if ans: | |
| return ans | |
| | |
+----------------------------------------------+-----------------------------------------------------------------------+
Avoid nested if and remove one indentation level.
copy.py
^^^^^^^
(See Appendix A for the origin of this example.)
+---------------------------------------------------------------+---------------------------------------------------------------+
| Current code | Replaced with |
+---------------------------------------------------------------+---------------------------------------------------------------+
| | |
| :: | :: |
| | |
| reductor = dispatch_table.get(cls) | if reductor := dispatch_table.get(cls): |
| if reductor: | rv = reductor(x) |
| rv = reductor(x) | elif reductor := getattr(x, "__reduce_ex__", None): |
| else: | rv = reductor(4) |
| reductor = getattr(x, "__reduce_ex__", None) | elif reductor := getattr(x, "__reduce__", None): |
| if reductor: | rv = reductor() |
| rv = reductor(4) | else: |
| else: | raise Error("un(deep)copyable object of type %s" % cls) |
| reductor = getattr(x, "__reduce__", None) | |
| if reductor: | |
| rv = reductor() | |
| else: | |
| raise Error( | |
| "un(deep)copyable object of type %s" % cls) | |
+---------------------------------------------------------------+---------------------------------------------------------------+
Code looks more regular and avoid multiple nested if.
datetime.py
^^^^^^^^^^^
+-----------------------------------------------------+-----------------------------------------------------+
| Current code | Replaced with |
+-----------------------------------------------------+-----------------------------------------------------+
| | |
| :: | :: |
| | |
| s = _format_time(self._hour, self._minute, | s = _format_time(self._hour, self._minute, |
| self._second, self._microsecond, | self._second, self._microsecond, |
| timespec) | timespec) |
| tz = self._tzstr() | if tz := self._tzstr(): |
| if tz: | s += tz |
| s += tz | return s |
| return s | |
| | |
+-----------------------------------------------------+-----------------------------------------------------+
*tz* is only used for ``s += tz``, moving its assignment inside the if
helps to show its scope.
sysconfig.py
^^^^^^^^^^^^
+------------------------------------+-----------------------------------------+
| Current code | Replaced with |
+------------------------------------+-----------------------------------------+
| | |
| :: | :: |
| | |
| while True: | while line := fp.readline(): |
| line = fp.readline() | if m := define_rx.match(line): |
| if not line: | n, v = m.group(1, 2) |
| break | try: |
| m = define_rx.match(line) | v = int(v) |
| if m: | except ValueError: |
| n, v = m.group(1, 2) | pass |
| try: | vars[n] = v |
| v = int(v) | elif m := undef_rx.match(line): |
| except ValueError: | vars[m.group(1)] = 0 |
| pass | |
| vars[n] = v | |
| else: | |
| m = undef_rx.match(line) | |
| if m: | |
| vars[m.group(1)] = 0 | |
| | |
+------------------------------------+-----------------------------------------+
Calling ``fp.readline()`` in the ``while`` condition and calling
``.match()`` on the if lines make the code more compact without making
it harder to understand.
Simplifying list comprehensions Simplifying list comprehensions
------------------------------- -------------------------------
@ -760,7 +881,7 @@ ruled::
is a vast improvment over the briefer:: is a vast improvment over the briefer::
yield (mylast := mylast[1])[0] yield (mylast := mylast[1])[0]
The original two statements are doing entirely different conceptual The original two statements are doing entirely different conceptual
things, and slamming them together is conceptually insane. things, and slamming them together is conceptually insane.
@ -804,7 +925,7 @@ pattern-matching reading, as::
if result := solution(xs, n): if result := solution(xs, n):
# use result # use result
It's also nice to trade away a small amount of horizontal whitespace It's also nice to trade away a small amount of horizontal whitespace
to get another _line_ of surrounding code on screen. I didn't give to get another _line_ of surrounding code on screen. I didn't give
much weight to this at first, but it was so very frequent it added up, much weight to this at first, but it was so very frequent it added up,
@ -835,7 +956,7 @@ is conceptually flat, "the first test that succeeds wins"::
if reductor := dispatch_table.get(cls): if reductor := dispatch_table.get(cls):
rv = reductor(x) rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None): elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4) rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None): elif reductor := getattr(x, "__reduce__", None):
rv = reductor() rv = reductor()
else: else:
@ -854,9 +975,9 @@ annoying "artificial" indentation level::
g = gcd(diff, n) g = gcd(diff, n)
if g > 1: if g > 1:
return g return g
became:: became::
if (diff := x - x_base) and (g := gcd(diff, n)) > 1: if (diff := x - x_base) and (g := gcd(diff, n)) > 1:
return g return g