<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Stepan Skriabin</title><author><name>Stepan Skriabin</name></author><id>https://teletype.in/atom/stepan_skryabin</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/stepan_skryabin?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@stepan_skryabin?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=stepan_skryabin"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/stepan_skryabin?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-14T21:42:10.551Z</updated><entry><id>stepan_skryabin:Etzsd7uknR5</id><link rel="alternate" type="text/html" href="https://teletype.in/@stepan_skryabin/Etzsd7uknR5?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=stepan_skryabin"></link><title>Измеряем продуктивность своей работы</title><published>2022-05-20T14:46:57.064Z</published><updated>2022-05-20T14:46:57.064Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/2b/e9/2be9fb4c-52dc-49a4-b3b0-37b7f6afd301.png"></media:thumbnail><category term="plaginy" label="Плагины"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/35/ff/35ffd134-6589-4bff-94f6-1e8261b8ae7a.png&quot;&gt;Когда я начал работать на удалёнке над первым своим коммерческим проектом мне было не понятно насколько эффективно я работаю и и сколько конкретно времени трачу на написание кода. Также в условиях удалёнки необходимо чётче следить за своим графиком, чтобы не сгореть к чертям и не провалить проект.</summary><content type="html">
  &lt;p id=&quot;syQB&quot;&gt;Когда я начал работать на удалёнке над первым своим коммерческим проектом мне было не понятно насколько эффективно я работаю и и сколько конкретно времени трачу на написание кода. Также в условиях удалёнки необходимо чётче следить за своим графиком, чтобы не сгореть к чертям и не провалить проект.&lt;/p&gt;
  &lt;p id=&quot;E3JP&quot;&gt;В своей работе я использую два простых инcтрумента: Pomodoro и WakaTime. Если про помидор все уже достаточно хорошо наслышали или даже пользуются, то второй инструмент не так популярен.&lt;/p&gt;
  &lt;h2 id=&quot;GP28&quot;&gt;WakaTime&lt;/h2&gt;
  &lt;p id=&quot;7vaM&quot;&gt;Проект озволяет отслеживать свою активность отправля статистику на сервера WakaTime. Отслеживается время работы, язык, название проекта, операционная система.  Полный список того какая информация передается можно посмотреть &lt;a href=&quot;https://wakatime.com/legal/privacy-policy&quot; target=&quot;_blank&quot;&gt;тут.&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;5ktz&quot;&gt;Киллерфичей для меня стало то, что отслеживается только активаня работа. Иными словами, запустить и свернуть окно IDE попивая чай не получится, время простоя не будет учитываться.&lt;/p&gt;
  &lt;p id=&quot;AKEe&quot;&gt;Для работы требуется создать аккаунт на wakatime.com (есть авторизация через гитхаб, а гугла нет) и установить плагин в любимую IDE из &lt;a href=&quot;https://wakatime.com/plugins&quot; target=&quot;_blank&quot;&gt;списка&lt;/a&gt; поддерживаемых. После чего в плагин надо всавить api-key который гененируется в персональных настройках wakatime.com. Через небольшой промежуток времени вся отслеживаемая информация появится в разделе &lt;strong&gt;Dashboard&lt;/strong&gt;.&lt;/p&gt;
  &lt;figure id=&quot;wzQz&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/35/ff/35ffd134-6589-4bff-94f6-1e8261b8ae7a.png&quot; width=&quot;960&quot; /&gt;
    &lt;figcaption&gt;красивые цветные картинки, на радость детям&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;R5Wb&quot;&gt;Есть как платная так и бесплатная подписка. Для индивидуального использования хватит и бесплатной подписки.&lt;/p&gt;
  &lt;p id=&quot;QD0K&quot;&gt;Кроме общей статистики, в разделе &lt;strong&gt;Projects&lt;/strong&gt; доступна возможность смотреть статистику по каждому проекту (или репозиторию) отдельно.&lt;/p&gt;
  &lt;p id=&quot;gh6V&quot;&gt;В разделе &lt;strong&gt;Share&lt;/strong&gt; есть возможность сгенерировать бирку (на которой указано общее время работы), тамже можно генерировать неплохие графики, сохраняя их в формате SVG, PNG. На удивление есть даже JSON, так что можно отрисовать график самостоятельно. Вся это красота может успешно использоваться в описании репы или в резюме.&lt;/p&gt;
  &lt;figure id=&quot;8Bs3&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d8/3e/d83e6078-695d-42d9-a9b0-5887c2fd8662.png&quot; width=&quot;960&quot; /&gt;
    &lt;figcaption&gt;Настройки генерации графиков.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;sPxm&quot;&gt;Можно настроить отправку раз в месяц/неделю/день статистики себе на почту или заспамить тимлида.&lt;/p&gt;
  &lt;p id=&quot;oUeF&quot;&gt;Для особо требовательных и рукастых есть описание АПИ (REST API) через который можно получить всю ту же информация что и через сайт. &lt;/p&gt;
  &lt;p id=&quot;vJkz&quot;&gt;Ну и как же не обойтись без &lt;s&gt;пиписькомерялки&lt;/s&gt; доски лидеров, где можно посоревноваться в длинне... рейтинга.&lt;/p&gt;
  &lt;figure id=&quot;gb4S&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/91/61/916131c9-803a-4cdb-9c00-ff0ae71c4d6e.png&quot; width=&quot;960&quot; /&gt;
    &lt;figcaption&gt;да, опять китайцы впереди&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;xvYj&quot;&gt;Кроме интеграцим с популярными системами хранения кода (GitHub, GitLab, Bitbucked) есть интеграция с Slack, Google Calendar. Полный список можно найти &lt;a href=&quot;https://wakatime.com/integrations/&quot; target=&quot;_blank&quot;&gt;тут&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;H2hi&quot;&gt;Вообще проект не настолько и молодой. Создан в 2013 году и к настоящему времени насчитывает около 60 поддерживаемых приложений, в основном разные IDE и редакторы кода, но есть не только они. Есть даже поддержка интерпретаторов bash, zsh, iTerm2, fish и даже Excel/Word.&lt;/p&gt;
  &lt;p id=&quot;8e6Y&quot;&gt;Итогом использования WakaTime для меня стало чёткое понимание своего физического уровня и количества времени которое я могу потратить на код и не умереть.&lt;/p&gt;

</content></entry><entry><id>stepan_skryabin:wg2R5jrbxnU</id><link rel="alternate" type="text/html" href="https://teletype.in/@stepan_skryabin/wg2R5jrbxnU?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=stepan_skryabin"></link><title>Python - очередь с приоритетом</title><published>2022-05-16T18:16:19.618Z</published><updated>2022-05-18T16:55:19.480Z</updated><summary type="html">В статье разбираем практический случай создания очереди с сортировкой по приоритету.</summary><content type="html">
  &lt;p id=&quot;fBU3&quot;&gt;В статье разбираем практический случай создания очереди с сортировкой по приоритету.&lt;/p&gt;
  &lt;h2 id=&quot;Простая-очередь.&quot;&gt;Простая очередь.&lt;/h2&gt;
  &lt;p id=&quot;CFxZ&quot;&gt;Самый просто пример использования очереди - это поэтапная обработка ссылок на скачиваение файлов. Для этого достаточно воспользоваться простейшим списком &lt;code&gt;list&lt;/code&gt; куда можно закидывать любой объект c помощью метода &lt;code&gt;.append()&lt;/code&gt;. В действительности &lt;code&gt;list&lt;/code&gt; не является настоящей очередью (&lt;em&gt;но сейчас это не важно&lt;/em&gt;). Получить объект содержащийся в такой “очереди” так же просто, для этого есть метод &lt;code&gt;.pop()&lt;/code&gt;. При этом стоит помнить, что метод &lt;code&gt;.pop()&lt;/code&gt; этот элемент удаляет навсегда.&lt;/p&gt;
  &lt;p id=&quot;yAbA&quot;&gt;Пример кода:&lt;/p&gt;
  &lt;pre id=&quot;Hcxm&quot; data-lang=&quot;python&quot;&gt;queue = []

item1 = &amp;quot;https://www.example.com/001.zip&amp;quot;
item2 = &amp;quot;https://www.example.com/002.zip&amp;quot;
item3 = &amp;quot;https://www.example.com/003.zip&amp;quot;

# Закинем в очередь объекты
queue.append(item1)
queue.append(item2)
queue.append(item3)

# Получаем из очереди объекты
queue.pop()
# Выведет:
queue.pop() # &amp;quot;https://www.example.com/003.zip&amp;quot;
queue.pop() # &amp;quot;https://www.example.com/002.zip&amp;quot;
queue.pop() # &amp;quot;https://www.example.com/001.zip&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;9xBp&quot;&gt;Вроде всё просто, но в данном случае простота не значит гибкость. Вот основные проблемы:&lt;/p&gt;
  &lt;ol id=&quot;UCF4&quot;&gt;
    &lt;li id=&quot;0OJV&quot;&gt;нет автоматической сортировки, элементы из списка можно получить с конца в начало (&lt;em&gt;если вызывать&lt;/em&gt; &lt;code&gt;.pop(0)&lt;/code&gt; - &lt;em&gt;с начала в конец&lt;/em&gt;);&lt;/li&gt;
    &lt;li id=&quot;cOGq&quot;&gt;при применении метода &lt;code&gt;.pop()&lt;/code&gt; к списку не содержащему элементов возникает исключение &lt;code&gt;IndexError&lt;/code&gt; которое нужно обработать.&lt;/li&gt;
    &lt;li id=&quot;cYwV&quot;&gt;нет гарантии что вы работаете однозначно с одним и тем же объектом &lt;code&gt;queue&lt;/code&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h2 id=&quot;Реализация-очереди-с-приоритетом.&quot;&gt;Реализация очереди с приоритетом.&lt;/h2&gt;
  &lt;p id=&quot;oMdl&quot;&gt;Для избежания недостатков простого &lt;code&gt;list&lt;/code&gt; предлагаю вооружится встроенным модулем &lt;code&gt;heapq&lt;/code&gt; (куча) и паттерном Синглтон.&lt;/p&gt;
  &lt;p id=&quot;ZYin&quot;&gt;Почему и зачем использовать модуль &lt;code&gt;heapq&lt;/code&gt;? Всё просто, этот модуль может просто и быстро отсортировать объекты по приоритету.&lt;/p&gt;
  &lt;p id=&quot;cHr2&quot;&gt;Паттерн &lt;strong&gt;Синглтон&lt;/strong&gt; здесь будет использоваться для гарантированной работы только с одним экземпляром объекта &lt;code&gt;Queue&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;sAmv&quot;&gt;Весь код класса &lt;code&gt;Queue&lt;/code&gt; приведён ниже:&lt;/p&gt;
  &lt;pre id=&quot;yJtl&quot; data-lang=&quot;python&quot;&gt;import heapq


class Queue:
    def __new__(cls):
        if not hasattr(cls, &amp;#x27;instance&amp;#x27;):
            cls.instance = super(Queue, cls).__new__(cls)
        return cls.instance
        
    def __init__(self):
        self.queue = []
        heapq.heapify(self.queue)
        self.index = 0
    
    def __str__(self):
        return f&amp;quot;Last index element in queue: {self.index}.&amp;quot;
    
    def __repr__(self):
        return f&amp;quot;Queue instance contains {self.queue.__len__()} elements.&amp;quot;
        
    def push(self, item, priority=False):
        priority_level = 1
        if priority:
            priority_level = -1
        entry = (priority_level, self.index, item)
        heapq.heappush(self.queue, entry)
        self.index = self.index + 1
        
    def pull(self):
        entry = heapq.heappop(self.queue)
        return entry[2]
   
     
# Использование:

scheduler = Queue()

item1 = &amp;quot;https://www.example.com/001.zip&amp;quot;
item2 = &amp;quot;https://www.example.com/002.zip&amp;quot;
item3 = &amp;quot;https://www.example.com/003.zip&amp;quot;

scheduler.push(item1)
scheduler.push(item2, priority=True)
scheduler.push(item3) 

# Вывод:
str(scheduler)   # Last index element in queue: 2.
repr(scheduler)  # Queue instance contains 3 elements.
scheduler.pull() # &amp;quot;https://www.example.com/002.zip&amp;quot;
scheduler.pull() # &amp;quot;https://www.example.com/001.zip&amp;quot;
scheduler.pull() # &amp;quot;https://www.example.com/003.zip&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;9Dye&quot;&gt;А теперь подробнее разберём код. Для начала импортируем необходимый модуль &lt;code&gt;heapq&lt;/code&gt; :&lt;/p&gt;
  &lt;pre id=&quot;7vGr&quot; data-lang=&quot;python&quot;&gt;import heapq&lt;/pre&gt;
  &lt;p id=&quot;Ygmg&quot;&gt;Дальше создадим класс &lt;code&gt;Queue&lt;/code&gt; и добавим в него конструктор &lt;code&gt;__new__&lt;/code&gt; и инициализатор &lt;code&gt;__init__&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;wq0u&quot; data-lang=&quot;python&quot;&gt;class Queue:
    def __new__(cls):
        if not hasattr(cls, &amp;#x27;instance&amp;#x27;):
            cls.instance = super().__new__(cls)
        return cls.instance&lt;/pre&gt;
  &lt;p id=&quot;YUw7&quot;&gt;Здесь я подробнее остановлюсь на конструкторе &lt;code&gt;__new__&lt;/code&gt;  (&lt;em&gt;это и будет наша реализация паттерна &lt;strong&gt;Синглтон&lt;/strong&gt;&lt;/em&gt;):&lt;/p&gt;
  &lt;p id=&quot;FdIR&quot;&gt;Для дальнейшего создания любого количества экземпляров класса &lt;code&gt;Queue&lt;/code&gt; которые будут гарантировано ссылаться только на один объект &lt;code&gt;Queue&lt;/code&gt; в памяти - можно воспользоваться “волшебным” методом &lt;code&gt;__new__&lt;/code&gt; который инициализируется в самом начале создания экземпляра класса.&lt;/p&gt;
  &lt;p id=&quot;r7Rg&quot;&gt;Итак, следите за руками:&lt;/p&gt;
  &lt;ol id=&quot;dw3r&quot;&gt;
    &lt;li id=&quot;MNMu&quot;&gt;С помощью метода &lt;code&gt;hasattr()&lt;/code&gt; сделаем проверку на отсутствие аттрибута &lt;code&gt;instance&lt;/code&gt; у вновь создаваемого экземпляра класса &lt;code&gt;Queue&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;mx38&quot;&gt;Если &lt;code&gt;instance&lt;/code&gt; нет - создадим аттрибут &lt;code&gt;instance&lt;/code&gt; и присвоим ему результат выполнения &lt;code&gt;super().__new__(cls)&lt;/code&gt; .&lt;/li&gt;
    &lt;li id=&quot;eBQu&quot;&gt;Если &lt;code&gt;instance&lt;/code&gt; в экземпляре есть - просто вернём содержимое &lt;code&gt;instance&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;vI7V&quot;&gt;Магия тут кроется в том что результатом первого вызова &lt;code&gt;super().__new__(cls)&lt;/code&gt; будет создан экземпляр класса &lt;code&gt;Queue&lt;/code&gt; , а все последующие попытки создать экземпляры класса &lt;code&gt;Queue&lt;/code&gt; вынужденно будут возвращать результат первого вызова &lt;code&gt;super()__new__(cls)&lt;/code&gt; .&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;dmPH&quot;&gt;Дальше идёт метод &lt;code&gt;__init__&lt;/code&gt; :&lt;/p&gt;
  &lt;pre id=&quot;2MWw&quot; data-lang=&quot;python&quot;&gt;def __init__(self):
    self.queue = []
    heapq.heapify(self.queue)
    self.index = 0&lt;/pre&gt;
  &lt;p id=&quot;epDd&quot;&gt;В котором мы создадим объект &lt;code&gt;self.queue&lt;/code&gt; - очередь с пустым списком &lt;code&gt;list&lt;/code&gt; . Для того чтобы превратить его в “кучу” &lt;code&gt;heap&lt;/code&gt; просто передадим &lt;code&gt;self.queue&lt;/code&gt; в качестве параметра в функцию &lt;code&gt;heapify()&lt;/code&gt;. Далее создадим объект с информацией о начальном  индексе &lt;code&gt;self.index&lt;/code&gt;. По умолчанию индекс = 0.&lt;/p&gt;
  &lt;p id=&quot;7dne&quot;&gt;Следующие методы &lt;code&gt;__str__&lt;/code&gt; и &lt;code&gt;__repr__&lt;/code&gt; имеют практическую ценность в случае отладки нашего кода (&lt;em&gt;но они не обязательны&lt;/em&gt;):&lt;/p&gt;
  &lt;pre id=&quot;RixL&quot; data-lang=&quot;python&quot;&gt;def __str__(self):
    return f&amp;quot;Last index element in queue: {self.index - 1}.&amp;quot;
    
def __repr__(self):
    return f&amp;quot;Queue instance contains {self.queue.__len__()} elements.&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;tk9V&quot;&gt;Метод &lt;code&gt;__str__&lt;/code&gt; будет выводить индекс присвоенный объекту в нашей очереди, который был добавлен последним. Метод &lt;code&gt;__repr__&lt;/code&gt; будет информировать об общем количестве элементов в очереди.&lt;/p&gt;
  &lt;p id=&quot;OuXt&quot;&gt;Метод &lt;code&gt;push()&lt;/code&gt; отвечает за добавление объекта в очередь:&lt;/p&gt;
  &lt;pre id=&quot;27gg&quot; data-lang=&quot;python&quot;&gt;def push(self, item: Any, priority=False):
    priority_level = 1
    if priority:
        priority_level = -1
    entry = (priority_level, self.index, item)
    heapq.heappush(self.queue, entry)
    self.index = self.index + 1&lt;/pre&gt;
  &lt;p id=&quot;fZiP&quot;&gt;&lt;code&gt;entry&lt;/code&gt; это кортеж с тремя элементами: приоритет, индекс, и сам объект. У каждого объекта помещаемого в очередь задается приоритет. Перед каждым помещением объекта в очередь приоритет сбрасывается на 1. Если &lt;code&gt;priority=True&lt;/code&gt; тогда объект в очередь помещается с приоритетом = -1. Теперь этот элемент будет в самом начале очереди, а значит наш метод &lt;code&gt;pull()&lt;/code&gt; выдаст его первым. Происходит это потому, что &lt;code&gt;heapq&lt;/code&gt; сортирует очередь исходя из “веса” элемента, с учётом его расположения. В случае наличия в очереди нескольких элементов с одинаковым приоритетом, сортировка будет осуществлятся по “весу” второго элемента - индекса. После добавления объекта в очередь, увеличиваем индекс на 1 пункт.&lt;/p&gt;
  &lt;p id=&quot;zbbV&quot;&gt;Метод &lt;code&gt;pull()&lt;/code&gt; отвечает за возврат объекта из очереди, с учётом приоритета:&lt;/p&gt;
  &lt;pre id=&quot;kQdh&quot; data-lang=&quot;python&quot;&gt;def pull(self):
    entry = heapq.heappop(self.queue)
    return entry[2]&lt;/pre&gt;
  &lt;p id=&quot;M22e&quot;&gt;Метод &lt;code&gt;.heappop()&lt;/code&gt; берёт из очереди объект у которого самое нижнее значение приоритета и номер индекса и выдаёт нам только последний (третий) элемент. Не забываем что нумерация идёт от 0.&lt;/p&gt;
  &lt;h2 id=&quot;Реализация-очереди-поддерживающую-работу-с-потоками.&quot;&gt;Реализация очереди поддерживающей работу с потоками.&lt;/h2&gt;
  &lt;p id=&quot;NHmU&quot;&gt;Код который мы написали выше не подходит для работы с множеством потоков (&lt;em&gt;используя модуль&lt;/em&gt; &lt;code&gt;threading&lt;/code&gt;). В случае использования потоков, где один пишет сообщение в очередь, а второй забирает это сообщение из очереди и обрабатывает его, может возникнуть блокировка очереди для одного из потоков, которая может привести к возникновению исключения. Для исправления проблемы понадобиться заменить модуль &lt;code&gt;heapq&lt;/code&gt; на &lt;code&gt;queue&lt;/code&gt; и изменить несколько строк в нашем классе &lt;code&gt;Queue&lt;/code&gt; .&lt;/p&gt;
  &lt;p id=&quot;mLoS&quot;&gt;Вот наши изменения:&lt;/p&gt;
  &lt;ol id=&quot;rXQZ&quot;&gt;
    &lt;li id=&quot;HCm9&quot;&gt;удаляем импорт модуля &lt;code&gt;heapq&lt;/code&gt; и добавляем импорт класса &lt;code&gt;PriorityQueue&lt;/code&gt; из модуля &lt;code&gt;queue&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;pk7q&quot;&gt;&lt;code&gt;self.queue = []&lt;/code&gt; меняем на &lt;code&gt;self.queue = PriorityQueue()&lt;/code&gt;, для создание экземпляра класса &lt;code&gt;PriorityQueue&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;F06Q&quot;&gt;удаляем строчку &lt;code&gt;heapq.heapify(self.queue)&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;vMJE&quot;&gt;в методе &lt;code&gt;__repr__()&lt;/code&gt; меняем &lt;code&gt;self.queue.__len__()&lt;/code&gt; на &lt;code&gt;self.queue._qsize()&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;LHZx&quot;&gt;&lt;code&gt;heapq.heappush(self.queue, entry)&lt;/code&gt; меняем на &lt;code&gt;self.queue.put(entry)&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;5CVX&quot;&gt;в методе &lt;code&gt;.pull()&lt;/code&gt; строчку &lt;code&gt;entry = heapq.heappop(self.queue)&lt;/code&gt; меняем на&lt;/li&gt;
  &lt;/ol&gt;
  &lt;pre id=&quot;3dDF&quot; data-lang=&quot;python&quot;&gt;if self.queue._qsize() == 0:
    return None
else:
    entry = self.queue.get()&lt;/pre&gt;
  &lt;p id=&quot;ERH1&quot;&gt;&lt;em&gt;Пояснение: в случае если количество элементов в очереди будет равно 0 &lt;code&gt;self.queue.get()&lt;/code&gt; будет выполнятся вечно, т.к. будет ожидать элемент из очереди. Для предотвращения такого поведения делаем проверку.&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;E5T6&quot;&gt;Итак, весь код выглядит вот так:&lt;/p&gt;
  &lt;pre id=&quot;Zpye&quot; data-lang=&quot;python&quot;&gt;from queue import PriorityQueue


class Queue:
    def __new__(cls):
        if not hasattr(cls, &amp;#x27;instance&amp;#x27;):
            cls.instance = super().__new__(cls)
        return cls.instance
    
    def __init__(self):
        self.queue = PriorityQueue()
        self.index = 0
    
    def __str__(self):
        return f&amp;quot;Last index element in queue: {self.index}&amp;quot;
    
    def __repr__(self):
        return f&amp;quot;Queue instance contains {self.queue._qsize()} elements.&amp;quot;
        
    def push(self, item, priority=False):
        priority_level = 1
        if priority:
            priority.level = -1
        entry = (priority_level, self.index, item)
        self.queue.put(entry)
        self.index = self.index + 1
        
    def pull(self):
        if self.queue._qsize() == 0:
            return None
        else:
            entry = self.queue.get()
        return entry[2]&lt;/pre&gt;
  &lt;p id=&quot;IXRl&quot;&gt;Таким образом наш класс &lt;code&gt;Queue&lt;/code&gt; теперь стал поддерживать работу с потоками.&lt;/p&gt;
  &lt;p id=&quot;ldEU&quot;&gt;Пример использования:&lt;/p&gt;
  &lt;pre id=&quot;vS4V&quot; data-lang=&quot;python&quot;&gt;from threading import Thread


scheduler = Queue()


def generate_links(item):
    for i in range(item):
        scheduler.push(i)
    # добавим одну приоритетную
    scheduler.push(item+1, priority=True)
    
    
def print_links():
    n=0
    while n is not None:
        n=scheduler.pull()
        print(f&amp;quot;Item in scheduler = {n}&amp;quot;)
        
        
first_thread = Thread(target=generate_links, name=&amp;#x27;Generator&amp;#x27;, args=(5,))
seconf_thread = Thread(target=print_links, name=&amp;#x27;Printer&amp;#x27;)

first_thread.start()
str(scheduler)   # Last index element in queue: 5.
repr(scheduler)  # Queue instance contains 6 elements.
seconf_thread.start() 

# Вывод:
# Item in schedule = 6
# Item in schedule = 0
# Item in schedule = 1
# Item in schedule = 2
# Item in schedule = 3
# Item in schedule = 4
# Item in schedule = None ## None - очередь пуста&lt;/pre&gt;

</content></entry></feed>