Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ² Python. ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅

Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. Π‘ΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„ΠΎΡ‚ΠΎ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. Π‘ΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. ΠšΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° ΠΏΡ€ΠΎ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. Π€ΠΎΡ‚ΠΎ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅
Автор ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ β€” Magdalena Tomczyk

Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΉ части ΡΡ‚Π°Ρ‚ΡŒΠΈ я описал основы использования Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ Ρ‚ΠΈΠΏΠΎΠ². Однако нСсколько Π²Π°ΠΆΠ½Ρ‹Ρ… ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ Π½Π΅ рассмотрСны. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ β€” Π²Π°ΠΆΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, Π²ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ… ΠΈΠ½ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ ΡƒΠ·Π½Π°Ρ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹Ρ… Ρ‚ΠΈΠΏΠ°Ρ… Π² Ρ€Π°Π½Ρ‚Π°ΠΉΠΌΠ΅. Но Π½Π°Ρ‡Π°Ρ‚ΡŒ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ с Π±ΠΎΠ»Π΅Π΅ простых Π²Π΅Ρ‰Π΅ΠΉ

ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ объявлСниС

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΎΠ½ создан. НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π΄Π°ΠΆΠ΅ Π½Π΅ запустится:

Π§Ρ‚ΠΎΠ±Ρ‹ это ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ, допустимо ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ строковый Π»ΠΈΡ‚Π°Ρ€Π°Π». Π’ этом случаС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Π±ΡƒΠ΄ΡƒΡ‚ вычислСны ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎ.

Π’Π°ΠΊ ΠΆΠ΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ классам ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ (ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ссли ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½): some_variable: ‘somemodule.SomeClass’

Π’ΠΎΠΎΠ±Ρ‰Π΅ говоря, Π² качСствС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ любоС вычислимоС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅. Однако рСкомСндуСтся ΠΈΡ… Π΄Π΅Π»Π°Ρ‚ΡŒ максимально простыми, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹ статичСского Π°Π½Π°Π»ΠΈΠ·Π° ΠΌΠΎΠ³Π»ΠΈ ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ. Π’ частности, скорСС всСго ΠΈΠΌΠΈ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ поняты динамичСски вычислимыС Ρ‚ΠΈΠΏΡ‹. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΏΡ€ΠΎ ограничСния Ρ‚ΡƒΡ‚: PEP 484 β€” Type Hints # Acceptable type hints

НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈ Π΄Π°ΠΆΠ΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Π±ΡƒΠ΄ΡƒΡ‚ доступны Π² Ρ€Π°Π½Ρ‚Π°ΠΉΠΌΠ΅, ΠΎΠ΄Π½Π°ΠΊΠΎ mypy Π½Π° Π½Π΅Π³ΠΎ выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ

UPD: Π’ Python 4.0 планируСтся Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ вычислСниС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ Ρ‚ΠΈΠΏΠΎΠ² (PEP 563), ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ этого ΠΏΡ€ΠΈΠ΅ΠΌΠ° со строковыми Π»ΠΈΡ‚Π΅Ρ€Π°Π»Π°ΠΌΠΈ. с Python 3.7 ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ конструкции from __future__ import annotations

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹

Для ситуаций, ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² качСствС callback) Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ Callable[[ArgType1, ArgType2. ], ReturnType]
НапримСр,

На Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ сигнатуру Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ числом ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΈΠ»ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹.

Generic-Ρ‚ΠΈΠΏΡ‹

Иногда Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΈΠΏΠ΅, ΠΏΡ€ΠΈ этом Π½Π΅ фиксируя Π΅Π³ΠΎ ТСстко. НапримСр, Ссли Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ…Ρ€Π°Π½ΠΈΡ‚ ΠΎΠ΄Π½ΠΎΡ‚ΠΈΠΏΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅. Или Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Ρ‚ΠΈΠΏΠ°, Ρ‡Ρ‚ΠΎ ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ².

Π’Π°ΠΊΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹ ΠΊΠ°ΠΊ List ΠΈΠ»ΠΈ Callable, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, ΠΌΡ‹ Π²ΠΈΠ΄Π΅Π»ΠΈ Ρ€Π°Π½ΡŒΡˆΠ΅ ΠΊΠ°ΠΊ Ρ€Π°Π· ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΎΠ². Но ΠΊΡ€ΠΎΠΌΠ΅ стандартных Ρ‚ΠΈΠΏΠΎΠ², Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свои Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊ-Ρ‚ΠΈΠΏΡ‹. Для этого Π½Π°Π΄ΠΎ, Π²ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, завСсти TypeVar ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, которая Π±ΡƒΠ΄Π΅Ρ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠΌ Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠ°, ΠΈ, Π²ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, нСпосрСдствСнно ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ generic-Ρ‚ΠΈΠΏ:

Как Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, для generic-Ρ‚ΠΈΠΏΠΎΠ² Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ автоматичСский Π²Ρ‹Π²ΠΎΠ΄ Ρ‚ΠΈΠΏΠ° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°.

Π’Π°ΠΊΠΆΠ΅, ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ TypeVar Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ допустимыС Ρ‚ΠΈΠΏΡ‹:

Иногда Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ статичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Π² этом случаС ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ cast. Π•Ρ‘ СдинствСнная Π·Π°Π΄Π°Ρ‡Π° β€” ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ. НапримСр:

Π’Π°ΠΊΠΆΠ΅ это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ²:

Π Π°Π±ΠΎΡ‚Π° с аннотациями Π²ΠΎ врСмя выполнСния

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ

НСсколько ΠΏΠΎΠ΄Π²ΠΎΠ΄Π½Ρ‹Ρ… ΠΊΠ°ΠΌΠ½Π΅ΠΉ статичСской Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ Π² Python

Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. Π‘ΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„ΠΎΡ‚ΠΎ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. Π‘ΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. ΠšΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° ΠΏΡ€ΠΎ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅. Π€ΠΎΡ‚ΠΎ Python Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅

Π”ΡƒΠΌΠ°ΡŽ, ΠΌΡ‹ всС ΠΏΠΎΡ‚ΠΈΡ…ΠΎΠ½ΡŒΠΊΡƒ ΡƒΠΆΠ΅ ΠΏΡ€ΠΈΠ²Ρ‹ΠΊΠ°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ Python Π΅ΡΡ‚ΡŒ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ²: ΠΈΡ… Π·Π°Π²Π΅Π·Π»ΠΈ Π΄Π²Π° Ρ€Π΅Π»ΠΈΠ·Π° Π½Π°Π·Π°Π΄ (3.5) Π² Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² (PEP 484), ΠΈ Π² ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΌ Ρ€Π΅Π»ΠΈΠ·Π΅ (3.6) ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ (PEP 526).

Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ±Π° этих PEP Π±Ρ‹Π»ΠΈ Π²Π΄ΠΎΡ…Π½ΠΎΠ²Π»Π΅Π½Ρ‹ MyPy, расскаТу, ΠΊΠ°ΠΊΠΈΠ΅ ТитСйскиС радости ΠΈ ΠΊΠΎΠ³Π½ΠΈΡ‚ΠΈΠ²Π½Ρ‹Π΅ диссонансы подстСрСгали мСня ΠΏΡ€ΠΈ использовании этого статичСского Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, Ρ€Π°Π²Π½ΠΎ ΠΊΠ°ΠΊ ΠΈ систСмы Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ Π² Ρ†Π΅Π»ΠΎΠΌ.

Disclamer: я Π½Π΅ поднимаю вопрос ΠΎ нСобходимости ΠΈΠ»ΠΈ врСдности статичСской Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈΠΈ Π² Python. ΠŸΡ€ΠΎΡΡ‚ΠΎ Ρ€Π°ΡΡΠΊΠ°Π·Ρ‹Π²Π°ΡŽ ΠΎ ΠΏΠΎΠ΄Π²ΠΎΠ΄Π½Ρ‹Ρ… камнях, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ натолкнулся Π² процСссС Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π² статичСски-Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ контСкстС.

Π”ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ (typing.Generic)

Однако, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ссли ΠΌΡ‹ пишСм Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ, ΠΈ программист, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ Π΅Π΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ статичСским Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ?
Π—Π°ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ класс Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, Π° ΠΏΠΎΡ‚ΠΎΠΌ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ‚ΠΈΠΏ?

Как-Ρ‚ΠΎ Π½Π΅ user-friendly.
А Ρ‡Ρ‚ΠΎ, Ссли хочСтся ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ?

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ я написал сСбС нСбольшой дСскриптор, Ρ€Π΅ΡˆΠ°ΡŽΡ‰ΠΈΠΉ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ:

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π² послСдствиС, Π½Π°Π΄ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ для Π±ΠΎΠ»Π΅Π΅ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ использования, Π½ΠΎ ΡΡƒΡ‚ΡŒ понятна.

[UPD]: Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ typing Иван ЛСвинский сказал, Ρ‡Ρ‚ΠΎ ΠΎΠ±Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° ΠΌΠΎΠ³ΡƒΡ‚ нСпрСдсказуСмо ΡΠ»ΠΎΠΌΠ°Ρ‚ΡŒΡΡ.

Anyway, you can use whatever way. Maybe __class_getitem__ is even slightly better, at least __class_getitem__ is a documented special method (although its behavior for generics is not).

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ алиасы

Π”Π°, с Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠ°ΠΌΠΈ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ просто:
К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, Ссли ΠΌΡ‹ Π³Π΄Π΅-Ρ‚ΠΎ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΊΠ°ΠΊ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, Ρ‚ΠΎ Π΅Π΅ аннотация автоматичСски прСвращаСтся ΠΈΠ· ΠΊΠΎΠ²Π°Ρ€ΠΈΠ°Π½Ρ‚Π½ΠΎΠΉ Π² ΠΊΠΎΠ½Ρ‚Ρ€Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π½ΡƒΡŽ:

И Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅, ΠΏΡ€Π΅Ρ‚Π΅Π½Π·ΠΈΠΉ ΠΊ Π»ΠΎΠ³ΠΈΠΊΠ΅ Ρƒ мСня Π½Π΅Ρ‚, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π΅ΡˆΠ°Ρ‚ΡŒ это приходится Ρ‡Π΅Ρ€Π΅Π· Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊ-алиасы:

ΠžΠ±Ρ€Π°Ρ‚Π½Π°Ρ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ

CΡ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π½ΠΎΠ΅ наслСдованиС (Stuctural Suptyping)

Однако, особой практичСской ΠΏΠΎΠ»ΡŒΠ·Ρ‹ Π² Ρ€Π°Π½Ρ‚Π°ΠΉΠΌΠ΅ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ со мноТСствСнным наслСдованиСм я Π½Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΈΠ».
ΠŸΠΎΡ…ΠΎΠΆΠ΅, Ρ‡Ρ‚ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ провСряСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° с Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, Π΄Π°ΠΆΠ΅ Π½Π΅ провСряя ΠΊΠΎΠ»-Π²ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Π½Π΅ говоря ΡƒΠΆΠ΅ ΠΎ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ:

C Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, MyPy, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, Π²Π΅Π΄Π΅Ρ‚ сСбя Π±ΠΎΠ»Π΅Π΅ ΡƒΠΌΠ½ΠΎ, ΠΈ подсвСчиваСт Π½Π΅ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ Ρ‚ΠΈΠΏΠΎΠ²:

ΠŸΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ²

БовсСм свСТая Ρ‚Π΅ΠΌΠ°, Ρ‚.ΠΊ. ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² с ΠΏΠΎΠ»Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠΎΠ±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒΡŽ ΠΏΡ€ΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ всС вСсСльС. Π­Ρ‚ΠΎΡ‚ вопрос ΡƒΠΆΠ΅ Π½Π΅ Ρ€Π°Π· всплывал Π² Π±Π°Π³-Ρ‚Ρ€Π΅ΠΊΠΊΠ΅Ρ€Π΅ MyPy, Π½ΠΎ ΠΎΠ½ Π΄ΠΎ сих ΠΏΠΎΡ€ ΠΊΠΎΠ΅-Π³Π΄Π΅ ругаСтся, ΠΈ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ смСло Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ.
Поясняю ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ:

Π’ΠΎ ΠΆΠ΅ касаСтся ΠΈ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ Π»ΡŽΠ±Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² сабклассов Π²ΠΈΠ΄Π°:

КоС-Π³Π΄Π΅ прСдупрСТдСния ΡƒΠΆΠ΅ ΠΏΠ΅Ρ€Π΅Π΅Ρ…Π°Π»ΠΈ Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ, ΠΊΠΎΠ΅-Π³Π΄Π΅ ΠΏΠΎΠΊΠ° ΡΡ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ Π½Π° ΠΏΡ€ΠΎΠ΄Π΅. Но ΠΎΠ±Ρ‰Π΅Π΅ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΈΠ±ΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ²: ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ допустимыми.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ

Π”ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ / ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ Π² ΠΏΠΈΡ‚ΠΎΠ½Π΅?

Как Python ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ сцСнарии ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ / шаблонного Ρ‚ΠΈΠΏΠ°? Π‘ΠΊΠ°ΠΆΠ΅ΠΌ, я Ρ…ΠΎΡ‡Ρƒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ внСшний Ρ„Π°ΠΉΠ» «BinaryTree.py» ΠΈ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹Π΅ Π΄Π΅Ρ€Π΅Π²ΡŒΡ, Π½ΠΎ для любого Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ….

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, я ΠΌΠΎΠ³ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΅ΠΌΡƒ Ρ‚ΠΈΠΏ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Как это дСлаСтся Π² Python?

10 ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²

Python ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ ΡƒΡ‚ΠΊΠΈ, поэтому Π΅ΠΌΡƒ Π½Π΅ трСбуСтся ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ синтаксис для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ‚ΠΈΠΏΠΎΠ².

Если Π²Ρ‹ ΠΈΠ· C ++ Ρ„ΠΎΠ½Π°, Π²Ρ‹ ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ, ΠΏΠΎΠΊΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ / классС шаблона, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° T (Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ синтаксиса), Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот Ρ‚ΠΈΠΏ < > Π² шаблонС.

Π˜Ρ‚Π°ΠΊ, Π² основном, это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚Π°ΠΊ ΠΆΠ΅:

Однако Π²Ρ‹ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Ссли Π²Ρ‹ Π½Π΅ Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΡΠ²Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠΎΠ² (которая ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π΅ рСкомСндуСтся), Π²Ρ‹ Π½Π΅ смоТСтС ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ содСрТало Ρ‚ΠΎΠ»ΡŒΠΊΠΎ элСмСнты Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

ПослС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ я ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π» нСсколько Ρ…ΠΎΡ€ΠΎΡˆΠΈΡ… мыслСй ΠΎ создании ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π² Python, я Π½Π°Ρ‡Π°Π» ΠΈΡΠΊΠ°Ρ‚ΡŒ Ρ‚Π΅Ρ…, Ρƒ ΠΊΠΎΠ³ΠΎ Π±Ρ‹Π»Π° такая ΠΆΠ΅ идСя, Π½ΠΎ я Π½Π΅ смог Π½Π°ΠΉΡ‚ΠΈ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ. Π˜Ρ‚Π°ΠΊ, Π²ΠΎΡ‚ ΠΎΠ½ΠΎ. Π― ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Π» это, ΠΈ это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ…ΠΎΡ€ΠΎΡˆΠΎ. Π­Ρ‚ΠΎ позволяСт Π½Π°ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ наши Ρ‚ΠΈΠΏΡ‹ Π² python.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ ΠΈΠ· этого ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

Π­Ρ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½ΠΎΠ΅ ΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ свои ограничСния. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ создаСтС ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ, ΠΎΠ½ создаСт Π½ΠΎΠ²Ρ‹ΠΉ Ρ‚ΠΈΠΏ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, нСсколько классов, Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… List( str ) Π² качСствС родитСля, Π±ΡƒΠ΄ΡƒΡ‚ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ Π΄Π²ΡƒΡ… ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… классов. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ΄ΠΎΠ»Π΅Ρ‚ΡŒ это, Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ dict для хранСния Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ класса ΠΈ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Ρ€Π°Π½Π΅Π΅ созданный Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ класс, Π° Π½Π΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ. Π­Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ созданиС Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ. Если интСрСсно, Π±ΠΎΠ»Π΅Π΅ элСгантноС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сдСлано с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈ / ΠΈΠ»ΠΈ мСтаклассов.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ python динамичСски Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½, это ΠΎΡ‡Π΅Π½ΡŒ просто. На самом Π΄Π΅Π»Π΅, Π²Π°ΠΌ придСтся ΠΏΡ€ΠΎΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ваш класс BinaryTree Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π» с ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ Ρ‚ΠΈΠΏΠΎΠΌ Π΄Π°Π½Π½Ρ‹Ρ….

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ случаи, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Ρ€Π°Π±ΠΎΡ‚Π°Π» с Π±Π°Π·ΠΎΠ²Ρ‹ΠΌΠΈ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΊΠ°ΠΊ строки ΠΈΠ»ΠΈ Ρ†Π΅Π»Ρ‹Π΅ числа. Π’Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΈΡ… Π² классС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΈΡ… Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с вашим ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΌ BinaryTree. Если это Π·Π²ΡƒΡ‡ΠΈΡ‚ слишком тяТСло, ΠΈ Π²Π°ΠΌ Π½ΡƒΠΆΠ½Π° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΈ простом Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠΈ строк, ΠΈΠ·Π²ΠΈΠ½ΠΈΡ‚Π΅, это Π½Π΅ Ρ‚ΠΎ, Π² Ρ‡Π΅ΠΌ Python Ρ…ΠΎΡ€ΠΎΡˆ.

На самом Π΄Π΅Π»Π΅ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠΈ Π² Python 3.5+. Π‘ΠΌ. PEP-484 ΠΈ Ρ‚ΠΈΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

Богласно ΠΌΠΎΠ΅ΠΉ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅, это Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ Π»Π΅Π³ΠΊΠΎ ΠΈ понятно, особСнно для Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ Π·Π½Π°ΠΊΠΎΠΌ с Java Generics, Π½ΠΎ всС Π΅Ρ‰Π΅ ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π΅Π½ для использования.

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Python 2 ΠΈΠ»ΠΈ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ Java-ΠΊΠΎΠ΄. Π˜Ρ… Π½Π΅ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ для этого. Π’ΠΎΡ‚ Ρ‡Ρ‚ΠΎ я ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽ Π·Π° Π½ΠΎΡ‡ΡŒ: https://github.com/FlorianSteenbuck/python-generics Π― Π΄ΠΎ сих ΠΏΠΎΡ€ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» компилятор, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²Ρ‹ сСйчас ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π΅Π³ΠΎ Ρ‚Π°ΠΊ:

Π—Π°Π΄Π°Ρ‡ΠΈ

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Python динамичСски Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½, Ρ‚ΠΈΠΏΡ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ значСния. Π›ΡƒΡ‡ΡˆΠ΅ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ я имСю Π² Π²ΠΈΠ΄Ρƒ, этот класс Π΄Π΅Ρ€Π΅Π²Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ‚ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ для своих Π΄Π²ΡƒΡ… Π²Π΅Ρ‚Π²Π΅ΠΉ:

И это ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

Π‘ этим Π½ΠΎΠ²Ρ‹ΠΌ мСтаклассом ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² ΠΎΡ‚Π²Π΅Ρ‚Π΅, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ я ΡΡΡ‹Π»Π°ΡŽΡΡŒ ΠΊΠ°ΠΊ:

Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΈΠΌΠ΅Π΅Ρ‚ нСсколько приятных прСимущСств

К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, Π±Ρ‹Π»ΠΈ прСдприняты Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ усилия для ΠΎΠ±Ρ‰Π΅Π³ΠΎ программирования Π½Π° python. БущСствуСт Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°: ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ

Он Π½Π΅ прогрСссировал Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠ½ΠΎΠ³ΠΈΡ… Π»Π΅Ρ‚, Π½ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ±Ρ‰Π΅Π΅ прСдставлСниС ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ свою ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ

Как Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ Π² Python

ΠΠ²Ρ‚ΠΎΡ€ΠΈΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ

Как Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ Π² Python

ΠŸΠ΅Ρ€Π²Ρ‹Π΅ упоминания ΠΎ подсказках Ρ‚ΠΈΠΏΠΎΠ² Π² языкС программирования Python появились Π² Π±Π°Π·Π΅ Python Enhancement Proposals (PEP-483). Π’Π°ΠΊΠΈΠ΅ подсказки Π½ΡƒΠΆΠ½Ρ‹ для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ статичСского Π°Π½Π°Π»ΠΈΠ·Π° ΠΊΠΎΠ΄Π° ΠΈ автодополнСния Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ риски появлСния Π±Π°Π³ΠΎΠ² Π² ΠΊΠΎΠ΄Π΅.

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрим основы Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π° Python ΠΈ Π΅Π΅ Ρ€ΠΎΠ»ΡŒ Π² динамичСски-Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ языкС, эта информация Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ»Π΅Π·Π½Π° для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ… Python-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ².

Випизация Π² Python

Для обозначСния Π±Π°Π·ΠΎΠ²Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ сами Ρ‚ΠΈΠΏΡ‹:

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования Π±Π°Π·ΠΎΠ²Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π² python-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

Π’Π°ΠΊΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ абстрактныС Ρ‚ΠΈΠΏΡ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

На ΠΏΠ΅Ρ€Π²ΠΎΠΌ мСстС стоит массив Ρ‚ΠΈΠΏΠΎΠ² Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΌ β€” Ρ‚ΠΈΠΏ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния.

ΠŸΡ€ΠΎ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ абстрактныС Ρ‚ΠΈΠΏΡ‹ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Python.

Π’Π°ΠΊΠΆΠ΅ Python позволяСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ свои Generic-Ρ‚ΠΈΠΏΡ‹.

Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ TypeVar ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ любого Ρ‚ΠΈΠΏΠ°, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠΈ. НапримСр:

На мСстС KeyType ΠΈΠ»ΠΈ ValueType ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹.

Π—Π°Ρ‡Π΅ΠΌ это Π½ΡƒΠΆΠ½ΠΎ

ЦСль β€” ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ Π½Π° ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΈΠ»ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. Π’ свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, это позволяСт ΡΠΎΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ количСство Π±Π°Π³ΠΎΠ², ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ написаниС ΠΊΠΎΠ΄Π° ΠΈ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ Π΅Π³ΠΎ качСство.

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΡ‰Π΅:

Однако, Π² ΠΎΠ±ΠΎΠΈΡ… случаях ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ ошибка, Ссли ΠΊΠ»ΡŽΡ‡ age Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΈ этом ΠΈΠΌΠ΅Ρ‚ΡŒ строковый Ρ‚ΠΈΠΏ. Валидация Ρ‚ΠΈΠΏΠΎΠ² добавляСт Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ строк ΠΊΠΎΠ΄Π°, Π½ΠΎ ΠΏΡ€ΠΈ большом количСствС ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΠΈΠΌΠ°Ρ‚ΡŒ Π½Π΅ΠΌΠ°Π»ΠΎ мСста Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅.

ИспользованиС Pydantic ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π²Π°Π»ΠΈΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΡ€ΠΈ этом Ρ‚ΠΈΠΏ автоматичСски помСняСтся Π½Π° Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΉ.

Как ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Π±ΠΎΠ»Π΅Π΅ строгая типизация ΠΊΠΎΠ΄Π° ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΡ€ΠΎΡ‰Π΅ ΠΈ бСзопаснСС. Однако, использованиС Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… возмоТностСй Pydantic ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ²Π»ΠΈΡΡ‚ΡŒ Π½Π° ΠΊΠΎΠ΄. Π’Π°ΠΊ, мутация Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈ Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ способна привСсти ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ значСния ΠΌΠΎΠ΄Π΅Π»ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ нСпонятСн. НапримСр:

Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ созданный User послС Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» ΡƒΠΊΠ°Π·Π°Π½ Π² ΠΌΠΎΠ΄Π΅Π»ΠΈ. Π­Ρ‚ΠΎ Π²Π΅Π΄Π΅Ρ‚ ΠΊ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌ ΠΊΡ€ΡƒΠΏΠ½Ρ‹ΠΌ Π±Π°Π³Π°ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π»ΡƒΡ‡ΡˆΠ΅ всСгда ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ.

Π’Π°ΠΊΠΆΠ΅ сСйчас Π½Π°Π±ΠΈΡ€Π°Π΅Ρ‚ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ ΠΏΠΎΠΏΡƒΠ»ΡΡ€Π½ΠΎΡΡ‚ΡŒ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ FastAPI, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, благодаря Pydantic, позволяСт быстро ΠΏΠΈΡΠ°Ρ‚ΡŒ Π²Π΅Π±-прилоТСния с автоматичСской Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠ΅ΠΉ Π΄Π°Π½Π½Ρ‹Ρ….

Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ эндпоинт /item автоматичСски Π²Π°Π»ΠΈΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ входящий json ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΊΠ°ΠΊ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡƒΡŽ модСль.

Π’Π°ΠΊΠΆΠ΅ для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ количСства Π±Π°Π³ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ mypy, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ статичСский Π°Π½Π°Π»ΠΈΠ· ΠΊΠΎΠ΄Π° Π½Π° соотвСтствиС Ρ‚ΠΈΠΏΠΎΠ². Π—Π° счСт этого Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹Ρ… Π±Π°Π³ΠΎΠ² ΠΈΠ»ΠΈ нСсоотвСтствий Ρ‚ΠΈΠΏΠΎΠ² Π² функциях.

И ΠΊΠ°ΠΊ бонус для Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ лСнится Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ. MonkeyType Π΄Π°Π΅Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ автоматичСски ΠΏΡ€ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ Π²ΠΎ всСх функциях, хотя послС запуска этой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ трСбуСтся ΠΏΡ€ΠΎΠΉΡ‚ΠΈΡΡŒ ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ ΠΈ ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ значСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ оказались распознаны Π½Π΅ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π»ΠΎΡΡŒ.

НововвСдСния Python 3.9.0

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрСли Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ Π² языкС Python. Π’ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π² Python становится Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ Π±ΠΎΠ»Π΅Π΅ Ρ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΌ ΠΈ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ Ρ€Π΅Π²ΡŒΡŽ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π΅ ΠΈ Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Π³Π»ΡƒΠΏΡ‹Ρ… ошибок. Π₯ΠΎΡ€ΠΎΡˆΠ΅Π΅ описаниС Ρ‚ΠΈΠΏΠΎΠ² Ρ‚Π°ΠΊΠΆΠ΅ позволяСт Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ быстрСС Π²Π»ΠΈΡ‚ΡŒΡΡ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ происходит, ΠΈ ΠΏΠΎΠ³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒΡΡ Π² Π·Π°Π΄Π°Ρ‡ΠΈ. Π’Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈ использовании ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ удаСтся Π² нСсколько Ρ€Π°Π· ΡΠΎΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ количСство строк ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π°Π½Π΅Π΅ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΈΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ² ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ

GenericsΠ’ΒΆ

Defining generic classesΠ’ΒΆ

Programs can also define new generic classes. Here is a very simple generic class that represents a stack:

Using Stack is similar to built-in container types:

Type inference works for user-defined generic types as well:

Construction of instances of generic types is also type checked:

Generic class internalsΠ’ΒΆ

Generic types could be instantiated or subclassed as usual classes, but the above examples illustrate that type variables are erased at runtime. Generic Stack instances are just ordinary Python objects, and they have no extra runtime overhead or magic due to being generic, other than a metaclass that overloads the indexing operator.

Defining sub-classes of generic classesΠ’ΒΆ

User-defined generic classes and generic classes defined in typing can be used as base classes for another classes, both generic and non-generic. For example:

Generic can be omitted from bases if there are other base classes that include type variables, such as Mapping[KT, VT] in the above example. If you include Generic[. ] in bases, then it should list all type variables present in other bases (or more, if needed). The order of type variables is defined by the following rules:

Generic functionsΠ’ΒΆ

Generic type variables can also be used to define generic functions:

As with generic classes, the type variable can be replaced with any type. That means first can be used with any sequence type, and the return type is derived from the sequence item type. For example:

Note also that a single definition of a type variable (such as T above) can be used in multiple generic functions or classes. In this example we use the same type variable in two generic functions:

A variable cannot have a type variable in its type unless the type variable is bound in a containing generic class or function.

Generic methods and generic selfΠ’ΒΆ

You can also define generic methods — just use a type variable in the method signature that is different from class type variables. In particular, self may also be generic, allowing a method to return the most precise type known at the point of access.

This feature is experimental. Checking code with type annotations for self arguments is still not fully implemented. Mypy may disallow valid code or allow unsafe code.

In this way, for example, you can typecheck chaining of setter methods:

Note also that mypy cannot always verify that the implementation of a copy or a deserialization method returns the actual type of self. Therefore you may need to silence mypy inside these methods (but not at the call site), possibly by making use of the Any type.

Variance of generic typesΠ’ΒΆ

Let us illustrate this by few simple examples:

This function needs a callable that can calculate a salary for managers, and if we give it a callable that can calculate a salary for an arbitrary employee, itΠ²Π‚™s still safe.

List is an invariant generic type. Naively, one would think that it is covariant, but let us consider this code:

Type variables with value restrictionΠ’ΒΆ

By default, a type variable can be replaced with any type. However, sometimes itΠ²Π‚™s useful to have a type variable that can only have some specific types as its value. A typical example is a type variable that can only have values str and bytes :

This is actually such a common type variable that AnyStr is defined in typing and we donΠ²Π‚™t need to define it ourselves.

We can use AnyStr to define a function that can concatenate two strings or bytes objects, but it canΠ²Π‚™t be called with other argument types:

Note that this is different from a union type, since combinations of str and bytes are not accepted:

In this case, this is exactly what we want, since itΠ²Π‚™s not possible to concatenate a string and a bytes object! The type checker will reject this function:

Another interesting special case is calling concat() with a subtype of str :

Type variables with upper boundsΠ’ΒΆ

In a call to such a function, the type T must be replaced by a type that is a subtype of its upper bound. Continuing the example above,

Type parameters of generic classes may also have upper bounds, which restrict the valid values for the type parameter in the same way.

A type variable may not have both a value restriction (see Type variables with value restriction ) and an upper bound.

Declaring decoratorsΠ’ΒΆ

One common application of type variable upper bounds is in declaring a decorator that preserves the signature of the function it decorates, regardless of that signature.

Note that class decorators are handled differently than function decorators in mypy: decorating a class does not erase its type, even if the decorator has incomplete type annotations.

HereΠ²Π‚™s a complete example of a function decorator:

From the final block we see that the signatures of the decorated functions foo() and bar() are the same as those of the original functions (before the decorator is applied).

The bound on F is used so that calling the decorator on a non-function (e.g. my_decorator(1) ) will be rejected.

Decorator factoriesΠ’ΒΆ

Functions that take arguments and return a decorator (also called second-order decorators), are similarly supported via generics:

Sometimes the same decorator supports both bare calls and calls with arguments. This can be achieved by combining with @overload :

Generic protocolsΠ’ΒΆ

The main difference between generic protocols and ordinary generic classes is that mypy checks that the declared variances of generic type variables in a protocol match how they are used in the protocol definition. The protocol in this example is rejected, since the type variable T is used covariantly as a return type, but the type variable is invariant:

This example correctly uses a covariant type variable:

See Variance of generic types for more about variance.

Generic protocols can also be recursive. Example:

Generic type aliasesΠ’ΒΆ

Type aliases can be imported from modules just like other names. An alias can also target another alias, although building complex chains of aliases is not recommended Π²Π‚β€œ this impedes code readability, thus defeating the purpose of using aliases. Example:

A type alias does not define a new type. For generic type aliases this means that variance of type variables used for alias definition does not apply to aliases. A parameterized generic alias is treated simply as an original type with the corresponding type variables substituted.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π’Π°Ρˆ адрСс email Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ *