PEP 572: Add examples from the stdlib by vstinner · Pull Request #695 · python/peps (original) (raw)
@@ -359,6 +359,125 @@ found in assignment statements:
Examples
========
Examples from the Python standard library
-----------------------------------------
site
^^^^
+-----------------------------------------------------+------------------------------------------------------------+
| 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.
decimal
^^^^^^^
+----------------------------------------------+-----------------------------------------------------------------------+
| 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
^^^^
+---------------------------------------------------------------+---------------------------------------------------------------+
| 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
^^^^^^^^
+-----------------------------------------------------+-----------------------------------------------------+
| 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
^^^^^^^^^
+------------------------------------+-----------------------------------------+
| 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
-------------------------------
@@ -760,7 +879,7 @@ ruled::
is a vast improvment over the briefer::
yield (mylast := mylast[1])[0]
The original two statements are doing entirely different conceptual
things, and slamming them together is conceptually insane.
@@ -804,7 +923,7 @@ pattern-matching reading, as::
if result := solution(xs, n):
# use result
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
much weight to this at first, but it was so very frequent it added up,
@@ -835,7 +954,7 @@ is conceptually flat, "the first test that succeeds wins"::
if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
@@ -854,9 +973,9 @@ annoying "artificial" indentation level::
g = gcd(diff, n)
if g > 1:
return g
became::
if (diff := x - x_base) and (g := gcd(diff, n)) > 1:
return g