Примеры из стандартной библиотеки Python
site.py env_base используется только в этих строках, при этом его присваивание присваивается if, перемещая его как «заголовок» блока.
Ток:
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base
Улучшено:
if env_base := os.environ.get("PYTHONUSERBASE", None):
return env_base
_pydecimal.py
Избегайте вложенных if и удалите один уровень отступа.
Ток:
if self._is_special:
ans = self._check_nans(context=context)
if ans:
return ans
Улучшено:
if self._is_special and (ans := self._check_nans(context=context)):
return ans
copy.py Код выглядит более регулярно и избегает многократного вложения. (Происхождение этого примера см. В приложении А.)
Ток:
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error(
"un(deep)copyable object of type %s" % cls)
Улучшено:
if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
raise Error("un(deep)copyable object of type %s" % cls)
datetime.py
tz используется только для s + = tz, перемещение его назначения внутри if помогает
показать свою сферу.
Ток:
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
tz = self._tzstr()
if tz:
s += tz
return s
Улучшено:
s = _format_time(self._hour, self._minute,
self._second, self._microsecond,
timespec)
if tz := self._tzstr():
s += tz
return s
sysconfig.py Вызов fp.readline () в условии while и вызов .match () в строках if делают код более компактным без
затрудняет понимание.
Ток:
while True:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
else:
m = undef_rx.match(line)
if m:
vars[m.group(1)] = 0
Улучшено:
while line := fp.readline():
if m := define_rx.match(line):
n, v = m.group(1, 2)
try:
v = int(v)
except ValueError:
pass
vars[n] = v
elif m := undef_rx.match(line):
vars[m.group(1)] = 0
Упрощение понимания списка. Понимание списка может эффективно отображать и фильтровать путем захвата условия:
results = [(x, y, x/y) for x in input_data if (y := f(x)) > 0]
Аналогично, подвыражение может быть повторно использовано в основном выражении,
присвоив ему имя при первом использовании:
stuff = [[y := f(x), x/y] for x in range(5)]
Обратите внимание, что в обоих случаях переменная y связана в содержащем
область действия (т.е. на том же уровне, что и результаты или материал).
Захват значений условий Выражения присваивания могут быть эффективно использованы в заголовке оператора if или while:
# Loop-and-a-half
while (command := input("> ")) != "quit":
print("You entered:", command)
# Capturing regular expression match objects
# See, for instance, Lib/pydoc.py, which uses a multiline spelling
# of this effect
if match := re.search(pat, text):
print("Found:", match.group(0))
# The same syntax chains nicely into 'elif' statements, unlike the
# equivalent using assignment statements.
elif match := re.search(otherpat, text):
print("Alternate found:", match.group(0))
elif match := re.search(third, text):
print("Fallback found:", match.group(0))
# Reading socket data until an empty string is returned
while data := sock.recv(8192):
print("Received data:", data)
Особенно с циклом while, это может избавить от необходимости иметь
бесконечный цикл, присваивание и условие. Это также создает
гладкая параллель между циклом, который просто использует вызов функции как
его состояние, и тот, который использует это как свое условие, но также использует
фактическое значение.
Fork Пример из мира UNIX низкого уровня:
if pid := os.fork():
# Parent code
else:
# Child code