🧩 РСализация ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°Β» Π½Π° Python

ΠœΠ΅Ρ‡Ρ‚Π°Π΅ΡˆΡŒ ΠΎ ΠΊΠΎΠ΄Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ ΡˆΠ²Π΅ΠΉΡ†Π°Ρ€ΡΠΊΠΈΠ΅ часы? ΠŸΠ°Ρ‚Ρ‚Π΅Ρ€Π½ Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°Β» ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ Ρ‚Π΅ΠΌ самым ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ заставит всС ΡˆΠ΅ΡΡ‚Π΅Ρ€Π΅Π½ΠΊΠΈ ΠΊΡ€ΡƒΡ‚ΠΈΡ‚ΡŒΡΡ идСально.

Π­Ρ‚ΠΎΡ‚ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» взят ΠΈΠ· нашСй СТСнСдСльной email-рассылки, посвящСнной бэкСнду. ΠŸΠΎΠ΄ΠΏΠΈΡˆΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π² числС ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΊΡ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ дайдТСст.

Π¨Π°Π±Π»ΠΎΠ½ Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°Β» (Singleton) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρƒ класса Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ экзСмпляр: ΠΊΠΎΠ³Π΄Π° создаСтся Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр, возвращаСтся ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ экзСмпляр, Π° Π½Π΅ создаСтся Π½ΠΎΠ²Ρ‹ΠΉ. Π­Ρ‚ΠΎ Π²Π°ΠΆΠ½ΠΎ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сСрвисами, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±Ρ‰ΠΈΠΌΠΈ для всСго прилоТСния: Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ ΠΈΠ»ΠΈ систСмой логирования, Π³Π΄Π΅ созданиС Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… экзСмпляров ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ нСэффСктивности ΠΈΠ»ΠΈ ошибкам.

ΠŸΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°Β» Π½Π° Python ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ – это функция, которая ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈΠ»ΠΈ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ класса. Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ позволяСт Β«ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒΒ» Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ»ΠΈ класс ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Π½Π΅ измСняя ΠΈΡ… структуру.

Π Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΊΠΎΠ΄ для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠΈΒ» с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π°:

Класс _SingletonWrapper. Π­Ρ‚ΠΎΡ‚ класс ΠΎΠ±eΡ€Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠΎΠΉ. Π’ конструкторС __init__ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ класс, сохраняСм Π΅Π³ΠΎ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ __wrapped__ ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ _instance ΠΊΠ°ΠΊ None. Π­Ρ‚ΠΎΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ СдинствСнный экзСмпляр класса:

class _SingletonWrapper:
    """
    Класс-ΠΎΠ±eΡ€Ρ‚ΠΊΠ° для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°.
    """
    def __init__(self, cls):
        self.__wrapped__ = cls  # ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ класс
        self._instance = None   # Π—Π΄Π΅ΡΡŒ Π±ΡƒΠ΄Π΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ экзСмпляр класса

ΠœΠ΅Ρ‚ΠΎΠ΄ __call__ позволяСт экзСмпляру класса вСсти сСбя ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΌ. Когда вызываСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΎΠ½ провСряСт, сущСствуСт Π»ΠΈ ΡƒΠΆΠ΅ экзСмпляр класса:

  • Если _instance Ρ€Π°Π²Π½ΠΎ None (экзСмпляр Π΅Ρ‰Π΅ Π½Π΅ создан), создаСтся Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр.
  • Если экзСмпляр ΡƒΠΆΠ΅ создан, ΠΎΠ½ просто возвращаСтся. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΡ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ класс Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ экзСмпляр.
    def __call__(self, *args, **kwargs):
        """Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ СдинствСнный экзСмпляр класса"""
        if self._instance is None:
            self._instance = self.__wrapped__(*args, **kwargs)
        return self._instance

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ singleton ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ класс Π² экзСмпляр _SingletonWrapper. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈ создании экзСмпляра класса Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Ссли ΠΎΠ½ Π±Ρ‹Π» создан Ρ€Π°Π½Π΅Π΅:

def singleton(cls):
    """
    Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ для класса, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ синглтон.
    """
    return _SingletonWrapper(cls)

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования шаблона

Если ΠΌΡ‹ ΠΎΠ±Π΅Ρ€Π½Π΅ΠΌ класс Logger Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ @singleton:

@singleton
class Logger:
    def __init__(self):
        self.log = []

    def write_log(self, message):
        self.log.append(message)

    def read_log(self):
        return self.log

Π’ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ попытаСмся ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр, Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ:

logger1 = Logger()
logger2 = Logger()
logger1.write_log("Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ 1")
print(logger2.read_log())  # Π’Ρ‹Π²Π΅Π΄Π΅Ρ‚: ['Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ 1']
print(logger1 is logger2)  # Π’Ρ‹Π²Π΅Π΄Π΅Ρ‚: True

Как Π²ΠΈΠ΄Π½ΠΎ, ΠΎΠ±Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° logger1 ΠΈ logger2 – это Π½Π° самом Π΄Π΅Π»Π΅ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ экзСмпляр.

ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π° использования Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠΈΒ»

Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°Β» – ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ ΠΏΡ€ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ. Π•Π³ΠΎ Π³Π»Π°Π²Π½Ρ‹Π΅ ΠΏΠ»ΡŽΡΡ‹:

  • Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ доступ – позволяСт Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ рСсурсами, Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΊΠ°ΠΊ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅.
  • Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ – ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ использованиС ΠΎΠ΄Π½ΠΎΠ³ΠΎ экзСмпляра ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ расход памяти ΠΈ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, особСнно для рСсурсоСмких ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².
  • Удобство тСстирования – Ρ‡Π΅Ρ€Π΅Π· Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ __wrapped__ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΌΡƒ классу для тСстирования, Π½Π΅ затрагивая ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅.

Когда Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°Β» ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ источником ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ

ΠŸΠ΅Ρ€Π΅Π΄ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ шаблона слСдуСт ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ контСкст – нСумСстноС использованиС Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠΈΒ» Ρ‡Ρ€Π΅Π²Π°Ρ‚ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ:

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

А Ρ‚Ρ‹ ΡƒΠΆΠ΅ использовал ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ°Β» Π² своих ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…? ПодСлись, Π² ΠΊΠ°ΠΊΠΈΡ… ситуациях ΠΎΠ½ Ρ‚Π΅Π±Π΅ пригодился!

***

Π₯ΠΎΡ‡Π΅ΡˆΡŒ ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒ Python ΠΈ Π½Π°ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Ρ‹ Π²Ρ€ΠΎΠ΄Π΅ Β«ΠžΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠΈΒ»? ΠšΡƒΡ€Ρ Β«ΠžΡΠ½ΠΎΠ²Ρ‹ программирования Π½Π° PythonΒ» ΠΎΡ‚ Proglib Academy ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚:

  • ПошаговоС ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΎΡ‚ простого ΠΊ слоТному
  • ΠŸΡ€Π°ΠΊΡ‚ΠΈΠΊΡƒ написания Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ²
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ… ΠΌΠ΅Π½Ρ‚ΠΎΡ€ΠΎΠ²

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

admin
11 дСкабря 2018

ООП Π½Π° Python: ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python допускаСт Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΠΈ, Π½ΠΎ Π² Π΅Π³ΠΎ основС...
admin
28 июня 2018

3 самых Π²Π°ΠΆΠ½Ρ‹Ρ… сфСры примСнСния Python: возмоТности языка

БущСствуСт мноТСство областСй примСнСния Python, Π½ΠΎ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ особСнно...
admin
13 фСвраля 2017

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python: ΠΎΡ‚ Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ° Π΄ΠΎ профСссионала

Пошаговая инструкция для всСх, ΠΊΡ‚ΠΎ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒΒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Python...