mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-06-16 17:49:52 +02:00
208 lines
10 KiB
Markdown
Vendored
208 lines
10 KiB
Markdown
Vendored
<p align="center"><img src="/images/logo.png#gh-light-mode-only" alt=""><img src="/images/logo-dark.png#gh-dark-mode-only" alt=""></p>
|
||
<h1 align="center">What the f*ck Python! 😱</h1>
|
||
<p align="center">Изучение и понимание Python с помощью нестандартного поведения и "магического" поведения.</p>
|
||
|
||
Переводы: [English Original](https://github.com/satwikkansal/wtfpython) [Chinese 中文](https://github.com/robertparley/wtfpython-cn) | [Vietnamese Tiếng Việt](https://github.com/vuduclyunitn/wtfptyhon-vi) | [Spanish Español](https://web.archive.org/web/20220511161045/https://github.com/JoseDeFreitas/wtfpython-es) | [Korean 한국어](https://github.com/buttercrab/wtfpython-ko) | [Russian Русский](https://github.com/nifadyev/wtfpython/tree/main/translations/README-ru.md) | [German Deutsch](https://github.com/BenSt099/wtfpython) | [Add translation](https://github.com/satwikkansal/wtfpython/issues/new?title=Add%20translation%20for%20[LANGUAGE]&body=Expected%20time%20to%20finish:%20[X]%20weeks.%20I%27ll%20start%20working%20on%20it%20from%20[Y].)
|
||
|
||
Альтернативные способы: [Интерактивный сайт](https://wtfpython-interactive.vercel.app) | [Интерактивный Jupiter notebook](https://colab.research.google.com/github/satwikkansal/wtfpython/blob/master/irrelevant/wtf.ipynb) | [CLI](https://pypi.python.org/pypi/wtfpython)
|
||
|
||
Python, будучи прекрасно спроектированным высокоуровневым языком программирования, предоставляет множество возможностей для удобства программиста. Но иногда результаты работы Python кода могут показаться неочевидными на первый взгляд.
|
||
|
||
**wtfpython** задуман как проект, пытающийся объяснить, что именно происходит под капотом некоторых неочевидных фрагментов кода и менее известных возможностей Python.
|
||
|
||
Если вы опытный программист на Python, вы можете принять это как вызов и правильно объяснить WTF ситуации с первой попытки. Возможно, вы уже сталкивались с некоторыми из них раньше, и я смогу оживить ваши старые добрые воспоминания! 😅
|
||
|
||
PS: Если вы уже читали **wtfpython** раньше, с изменениями можно ознакомиться [здесь](https://github.com/satwikkansal/wtfpython/releases/) (примеры, отмеченные звездочкой - это примеры, добавленные в последней основной редакции).
|
||
|
||
Ну что ж, приступим...
|
||
|
||
# Содержание
|
||
|
||
- [Содержание](#содержание)
|
||
- [Структура примера](#структура-примера)
|
||
- [Применение](#применение)
|
||
- [👀 Примеры](#-примеры)
|
||
- [Секция: Напряги мозги!](#секция-напряги-мозги)
|
||
- [▶ Первым делом!](#-первым-делом)
|
||
- [💡 Обьяснение](#-обьяснение)
|
||
|
||
# Структура примера
|
||
|
||
Все примеры имеют следующую структуру:
|
||
|
||
> ### ▶ Какой-то заголовок
|
||
>
|
||
> ```py
|
||
> # Неочевидный фрагмент кода
|
||
> # Подготовка к магии...
|
||
> ```
|
||
>
|
||
> **Вывод (Python версия):**
|
||
>
|
||
> ```py
|
||
> >>> triggering_statement
|
||
> Неожиданные результаты
|
||
> ```
|
||
>
|
||
> (Опционально): Краткое описание неожиданного результата
|
||
>
|
||
>
|
||
> #### 💡 Объяснение
|
||
>
|
||
> * Краткое объяснение того, что происходит и почему это происходит.
|
||
>
|
||
> ```py
|
||
> # Код
|
||
> # Дополнительные примеры для дальнейшего разъяснения (если необходимо)
|
||
> ```
|
||
>
|
||
> **Вывод (Python версия):**
|
||
>
|
||
> ```py
|
||
> >>> trigger # какой-нибудь пример, позволяющий легко раскрыть магию
|
||
> # обоснованный вывод
|
||
> ```
|
||
|
||
**Важно:** Все примеры протестированы на интерактивном интерпретаторе Python 3.5.2, и они должны работать для всех версий Python, если это явно не указано перед выводом.
|
||
|
||
# Применение
|
||
|
||
Хороший способ получить максимальную пользу от этих примеров - читать их последовательно, причем для каждого из них важно:
|
||
|
||
- Внимательно изучить исходный код. Если вы опытный программист на Python, то в большинстве случаев сможете предугадать, что произойдет дальше.
|
||
- Прочитать фрагменты вывода и,
|
||
- Проверить, совпадают ли выходные данные с вашими ожиданиями.
|
||
- Убедиться, что вы знаете точную причину, по которой вывод получился именно таким.
|
||
- Если ответ отрицательный (что совершенно нормально), сделать глубокий вдох и прочитать объяснение (а если пример все еще непонятен, и создайте issue [здесь](https://github.com/satwikkansal/wtfpython/issues/new)).
|
||
- Если "да", ощутите мощь своих познаний в Python и переходите к следующему примеру.
|
||
|
||
PS: Вы также можете читать WTFPython в командной строке, используя [pypi package](https://pypi.python.org/pypi/wtfpython),
|
||
|
||
```sh
|
||
pip install wtfpython -U
|
||
wtfpython
|
||
```
|
||
|
||
# 👀 Примеры
|
||
|
||
## Секция: Напряги мозги!
|
||
|
||
### ▶ Первым делом!
|
||
|
||
<!-- Example ID: d3d73936-3cf1-4632-b5ab-817981338863 -->
|
||
<!-- read-only -->
|
||
|
||
По какой-то причине "моржовый оператор" (англ. walrus) `:=` в Python 3.8 стал довольно популярным. Давайте проверим его,
|
||
|
||
1\.
|
||
|
||
```py
|
||
# Python version 3.8+
|
||
|
||
>>> a = "wtf_walrus"
|
||
>>> a
|
||
'wtf_walrus'
|
||
|
||
>>> a := "wtf_walrus"
|
||
File "<stdin>", line 1
|
||
a := "wtf_walrus"
|
||
^
|
||
SyntaxError: invalid syntax
|
||
|
||
>>> (a := "wtf_walrus") # А этот код работает
|
||
'wtf_walrus'
|
||
>>> a
|
||
'wtf_walrus'
|
||
```
|
||
|
||
2 \.
|
||
|
||
```py
|
||
# Python version 3.8+
|
||
|
||
>>> a = 6, 9
|
||
>>> a
|
||
(6, 9)
|
||
|
||
>>> (a := 6, 9)
|
||
(6, 9)
|
||
>>> a
|
||
6
|
||
|
||
>>> a, b = 6, 9 # Типичная распаковка
|
||
>>> a, b
|
||
(6, 9)
|
||
>>> (a, b = 16, 19) # Упс
|
||
File "<stdin>", line 1
|
||
(a, b = 16, 19)
|
||
^
|
||
SyntaxError: invalid syntax
|
||
|
||
>>> (a, b := 16, 19) # На выводе получаем странный кортеж из 3 элементов
|
||
(6, 16, 19)
|
||
|
||
>>> a # Значение переменной остается неизменной?
|
||
6
|
||
|
||
>>> b
|
||
16
|
||
```
|
||
|
||
#### 💡 Обьяснение
|
||
|
||
**Быстрый разбор что такое "моржовый оператор"**
|
||
|
||
"Моржовый оператор" (`:=`) был представлен в Python 3.8, может быть полезен в ситуациях, когда вы хотите присвоить значения переменным в выражении.
|
||
|
||
```py
|
||
def some_func():
|
||
# Предположим, что здесь выполняются требовательные к ресурсам вычисления
|
||
# time.sleep(1000)
|
||
return 5
|
||
|
||
# Поэтому вместо,
|
||
if some_func():
|
||
print(some_func()) # Плохая практика, поскольку вычисления происходят дважды.
|
||
|
||
# Или
|
||
a = some_func()
|
||
if a:
|
||
print(a)
|
||
|
||
# Можно лаконично написать
|
||
if a := some_func():
|
||
print(a)
|
||
```
|
||
|
||
**Вывод (> 3.8):**
|
||
|
||
```py
|
||
5
|
||
5
|
||
5
|
||
```
|
||
|
||
Использование `:=` сэкономило одну строку кода и неявно предотвратило вызов `some_func` дважды.
|
||
|
||
- "выражение присваивания", не обернутое в скобки, иначе говоря использование моржового оператора, ограничено на верхнем уровне, отсюда `SyntaxError` в выражении `a := "wtf_walrus"` в первом фрагменте. После оборачивания в скобки, `a` было присвоено значение, как и ожидалось.
|
||
|
||
- В то же время оборачивание скобками выражения, содержащего оператор `=`, не допускается. Отсюда синтаксическая ошибка в `(a, b = 6, 9)`.
|
||
|
||
- Синтаксис моржового оператора имеет вид `NAME:= expr`, где `NAME` - допустимый идентификатор, а `expr` - допустимое выражение. Следовательно, упаковка и распаковка итерируемых объектов не поддерживается, что означает,
|
||
|
||
- `(a := 6, 9)` эквивалентно `((a := 6), 9)` и в конечном итоге `(a, 9)` (где значение `a` равно `6`)
|
||
|
||
```py
|
||
>>> (a := 6, 9) == ((a := 6), 9)
|
||
True
|
||
>>> x = (a := 696, 9)
|
||
>>> x
|
||
(696, 9)
|
||
>>> x[0] is a # Оба ссылаются на одну и ту же ячейку памяти
|
||
True
|
||
```
|
||
|
||
- Аналогично, `(a, b := 16, 19)` эквивалентно `(a, (b := 16), 19)`, которое есть не что иное, как кортеж из 3 элементов.
|
||
|
||
---
|