<?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>@snakeblog</title><author><name>@snakeblog</name></author><id>https://teletype.in/atom/snakeblog</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/snakeblog?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/snakeblog?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-17T22:06:34.913Z</updated><entry><id>snakeblog:rJZFxHmE7</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/rJZFxHmE7?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Зачем нужны or и and в Python?</title><published>2018-08-21T14:37:36.022Z</published><updated>2018-08-21T14:37:36.022Z</updated><summary type="html">Сначала может показаться, что вопрос в заголовке, как минимум, странный и в чём-то даже глупый, но не всё так просто. Как известно, в языке Python есть побитовые операции &amp;(и), |(или), а также ^(строгое или). Однако есть ещё &quot;словесные&quot; братья and и or, которые используются в условиях. Однако зачем они нужны, если можно использовать &amp; и | вместо них и всё будет работать? На этот вопрос мы и попытаемся ответить в данной статье. Для начала лучше вникнем в суть происходящего:</summary><content type="html">
  &lt;p&gt;Сначала может показаться, что вопрос в заголовке, как минимум, странный и в чём-то даже глупый, но не всё так просто. Как известно, в языке Python есть побитовые операции &amp;amp;(и), |(или), а также ^(строгое или). Однако есть ещё &amp;quot;словесные&amp;quot; братья and и or, которые используются в условиях. Однако зачем они нужны, если можно использовать &amp;amp; и | вместо них и всё будет работать? На этот вопрос мы и попытаемся ответить в данной статье. Для начала лучше вникнем в суть происходящего:&lt;/p&gt;
  &lt;pre&gt;print(True or False) # True
print(True | False)  # True
print(True and False)  # False
print(True &amp;amp; False)  # False
&lt;/pre&gt;
  &lt;p&gt;Как можно заметить, результат они выдают одинаковый. Так в чём же разница? Ответить можно одним словом - &lt;em&gt;оптимизация&lt;/em&gt;. Наглядно это проиллюстрирует следующий пример:&lt;/p&gt;
  &lt;pre&gt;def print_and_return(boolean):
	print(boolean)
	return boolean

print(&amp;quot;Обычный |&amp;quot;)
res1 = print_and_return(True) | print_and_return(False)
print(&amp;quot;Словесный or&amp;quot;)
res2 = print_and_return(True) or print_and_return(False)
&lt;/pre&gt;
  &lt;p&gt;В первом случае, выведутся все 2 значения: результат первой функции, результат второй. А вот во втором случае, нас ждёт сюрприз: второго вызова функции не произойдёт. Почему? Потому что or умеет оптимизировать обработку условий: результат будет истинным независимо от второго условия: ведь первое истинно - так зачем нужно считать второе?&lt;/p&gt;
  &lt;p&gt;То же самое с and:&lt;/p&gt;
  &lt;pre&gt;  def print_and_return(boolean):
  	print(boolean)
  	return boolean
  
  print(&amp;quot;Обычный &amp;amp;&amp;quot;)
  res1 = print_and_return(False) &amp;amp; print_and_return(True)
  print(&amp;quot;Словесный and&amp;quot;)
  res2 = print_and_return(False) and print_and_return(True)
&lt;/pre&gt;
  &lt;p&gt;Понятно, что условие ложно после вычисления первого выражения и and пропускает второе, сразу выдавая результат.&lt;/p&gt;
  &lt;p&gt;Теперь должно стать ясно, что для условий &amp;quot;выгоднее&amp;quot; использовать or и and вместо | и &amp;amp;, кроме тех случаев, когда необходимо выполнение всех частей условия. Например :&lt;/p&gt;
  &lt;pre&gt;(a != 0) and (1 / a)
&lt;/pre&gt;
  &lt;p&gt;никогда не выкинет ошибку деления на ноль. Думаю, таких применений можно придумать массу, но это занятие я оставляю вам, а сам расскажу про ещё одну интересную особенность or и and.&lt;/p&gt;
  &lt;p&gt;Их можно использовать для inline выражений не только с bool, но и с любыми другими типами, которые приводятся к логическому. Рассмотрим следующие выражения:&lt;/p&gt;
  &lt;pre&gt;print(3 or 10) # 3
print(&amp;quot;&amp;quot; or 5) # 5
print(&amp;quot;&amp;quot; and 20) # Выведет пустую строку
print(3 and 10) # 10
&lt;/pre&gt;
  &lt;p&gt;То есть оператор or работает по принципу: если первое выражение - истина, то возвращаем его, иначе возвращаем второе.&lt;/p&gt;
  &lt;p&gt;And работает по-другому: если первое - ложь, то возвращаем его, иначе вернём второе.&lt;/p&gt;
  &lt;p&gt;Думаю, теперь вы разобрались, как работают эти 2 оператора и сможете эффективно использовать их особенности в своих программах.&lt;/p&gt;
  &lt;p&gt;На этом всё.&lt;/p&gt;
  &lt;p&gt;До новых встреч в группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:S1evxIgrX</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/S1evxIgrX?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Разница между __str__ и __repr__</title><published>2018-08-02T09:35:20.489Z</published><updated>2018-08-02T09:35:20.489Z</updated><summary type="html">Во многих курсах по Python упоминают только один из этих двух &quot;магических&quot; методов и применяют их для одной цели: превращение объекта в строку. Считаю такой подход неправильным и поэтому расскажу, когда какой метод стоит применять.</summary><content type="html">
  &lt;p&gt;Во многих курсах по Python упоминают только один из этих двух &amp;quot;магических&amp;quot; методов и применяют их для одной цели: превращение объекта в строку. Считаю такой подход неправильным и поэтому расскажу, когда какой метод стоит применять.&lt;/p&gt;
  &lt;p&gt;Примером для дальнейшего описания послужит простенький класс точки на плоскости:&lt;/p&gt;
  &lt;pre&gt;class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y 
&lt;/pre&gt;
  &lt;p&gt;Давайте, для начала, определим метод __str__ у нашего класса и посмотрим, что выйдет&lt;/p&gt;
  &lt;pre&gt;class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y                                
                                         
  def __str__(self, x, y):                           
    return &amp;quot;Point, x={}, y={}&amp;quot;.format(x, y)

point = Point(1, 2)
print(point) 
&lt;/pre&gt;
  &lt;p&gt;Как мы и ожидаем увидеть, вывод будет следующим:&lt;/p&gt;
  &lt;pre&gt;Point, x=1, y=2
&lt;/pre&gt;
  &lt;p&gt;Загвоздка в том, что если мы переименуем __str__ в __repr__, то в выводе изменится... ровно ничего. А теперь давайте определим и тот и другой, но немного по-разному.&lt;/p&gt;
  &lt;pre&gt;class Point:                                   
  def __init__(self, x, y):                          
    self.x = x                                
    self.y = y                                
                                         
  def __repr__(self):                             
    return &amp;quot;repr: Point, x={}, y={}&amp;quot;.format(self.x, self.y)         
                                         
  def __str__(self):                              
    return &amp;quot;str: Point, x={}, y={}&amp;quot;.format(self.x, self.y)          
                                         
point = Point(5, 6)                               
print(point) 
&lt;/pre&gt;
  &lt;p&gt;Вывод будет следующим:&lt;/p&gt;
  &lt;pre&gt;str: Point, x=5, y=6
&lt;/pre&gt;
  &lt;p&gt;Значит, при превращении объекта в строку, преимущество имеет __str__, да и его название говорит о том, что это и есть его назначение. Но зачем тогда нужен точно такой же __repr__? Суть в том, что не такой же. Откройте интерпретатор и вставьте туда наш класс. А теперь введите&lt;/p&gt;
  &lt;pre&gt;point = Point(1, 2)
point
&lt;/pre&gt;
  &lt;p&gt;Выводом послужит следующая строка:&lt;/p&gt;
  &lt;pre&gt;repr: Point, x=1, y=2
&lt;/pre&gt;
  &lt;p&gt;То есть для того, чтобы выводить объект в интерпретаторе, преимущество имеет repr.&lt;/p&gt;
  &lt;p&gt;Вывод: используйте __str__ для превращения объекта в строку, а __repr__, когда хотите получать какую-то информацию в интерпретаторе при дебаге. Да, они взаимозаменяемы, но созданы они для разных целей.&lt;/p&gt;
  &lt;p&gt;Тем временем наше маленькое расследование подошло к концу.&lt;/p&gt;
  &lt;p&gt;Буду рад, если вы подпишетесь на мою группу &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:Skc4E26Em</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/Skc4E26Em?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Python: ссылки или значения?</title><published>2018-07-31T10:04:34.459Z</published><updated>2018-07-31T16:38:05.238Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/fc/fcd8945c-782e-47e6-98af-54a80d829e97.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://i.ytimg.com/vi/NVzUGZxeNH4/maxresdefault.jpg&quot;&gt;Как вы думаете, что происходит, когда вы пишете следующее выражение?</summary><content type="html">
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://i.ytimg.com/vi/NVzUGZxeNH4/maxresdefault.jpg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Как вы думаете, что происходит, когда вы пишете следующее выражение?&lt;/p&gt;
  &lt;pre&gt;a = b
&lt;/pre&gt;
  &lt;p&gt;Логичным, однако не совсем корректным ответом, будет &amp;quot;переменной a присваивается значение b&amp;quot;. Простой пример:&lt;/p&gt;
  &lt;pre&gt;first = [1, 2, 3]
second = first
second[0] = 5
# first = [5, 2, 3]
&lt;/pre&gt;
  &lt;p&gt;Если бы second просто присваивалось значение first, то при изменении second first не менялась бы. Однако это произошло. Cуть в том, что в python все объекты передаются по ссылке(а это объекты класса list). То есть для python всё равно, что вы напишете - first или second - они указывают на одну область в памяти и изменения, сделанные в значении одной переменной, отобразятся и во второй. Однако надо понимать разницу между &lt;em&gt;изменением&lt;/em&gt; и &lt;em&gt;присвоением&lt;/em&gt; ей нового значения:&lt;/p&gt;
  &lt;pre&gt;first = [1, 2, 3]
second = first
second = [2, 3, 4]
# first не изменился
&lt;/pre&gt;
  &lt;p&gt;После присвоения second значения [2, 3, 4] эта переменная теперь указывает на новую область памяти и уже никак не связана с first.&lt;/p&gt;
  &lt;p&gt;Абсолютно тот же механизм использует передача аргументов в функцию:&lt;/p&gt;
  &lt;pre&gt;def change_value(value):
    value[0] = 10
    value = [3, 4, 5]

a = [1, 2, 3]
change_value(a)
# a = [10, 2, 3]
&lt;/pre&gt;
  &lt;p&gt;Первая строчка в функции изменяет значение в памяти, а вторая создаёт ссылку на новую область памяти, а значит связь value с a теряется.&lt;/p&gt;
  &lt;p&gt;Понимание этого механизма может облегчить вам жизнь при работе с данными в Python.&lt;/p&gt;
  &lt;p&gt;Например может показаться, что следующий код создаёт двумерный список 3 на 3, заполненный нулями&lt;/p&gt;
  &lt;pre&gt;a = [[0] * 3] * 3  # a = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
&lt;/pre&gt;
  &lt;p&gt;Однако это не совсем тот список, который мы ожидаем увидеть: список [0, 0, 0] передаётся по ссылке, а значит все три вложенных списка указывают на одну область памяти.&lt;/p&gt;
  &lt;pre&gt;a[0][0] = 1  # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
&lt;/pre&gt;
  &lt;p&gt;Нетрудно заметить, что изменились все 3 списка, то есть толку от них мало. &amp;quot;Правильным&amp;quot; созданием такого списка было бы&lt;/p&gt;
  &lt;pre&gt;a = [[0] * 3 for _ in range(3)]
&lt;/pre&gt;
  &lt;p&gt;В этом выражении, каждый новый элемент - новая область в памяти, а значит вложенные списки независимы:&lt;/p&gt;
  &lt;pre&gt;a[0][0] = 1  # [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
&lt;/pre&gt;
  &lt;p&gt;Надеюсь, теперь вы разобрались в этой теме и не будете совершать ошибок, как в примере с массивом.&lt;/p&gt;
  &lt;p&gt;Подписывайтесь на группу &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:ByI5SQ54X</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/ByI5SQ54X?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Тестируем код в Python: unittest</title><published>2018-07-28T17:19:09.676Z</published><updated>2018-07-29T04:43:32.421Z</updated><summary type="html">Вспомните, когда вы в последний раз писали программу и она запускалась с первого раза, и в ней потом не было найдено багов. Тоже вспомнили &quot;Hello world!&quot;?;) Написание кода, а особенно длинного, требует огромной внимательности, однако даже если вы ей обладаете, то не факт, что в вашем коде не будет проблем. Бывает так, что о них вы узнаёте через продолжительное время, в самый неподходящий момент. Так как же предупредить эти самые проблемы? Очевидно, надо тестировать свою программу. Однако как? Не вручную же вбивать много разных данных в функции и смотреть, тот ли результат. Постойте, мы же с вами написали какую-то программу, а что нам мешает написать другую программу, которая будет тестировать первую? Специально для таких программ...</summary><content type="html">
  &lt;p&gt;Вспомните, когда вы в последний раз писали программу и она запускалась с первого раза, и в ней потом не было найдено багов. Тоже вспомнили &amp;quot;Hello world!&amp;quot;?;) Написание кода, а особенно длинного, требует огромной внимательности, однако даже если вы ей обладаете, то не факт, что в вашем коде не будет проблем. Бывает так, что о них вы узнаёте через продолжительное время, в самый неподходящий момент. Так как же предупредить эти самые проблемы? Очевидно, надо тестировать свою программу. Однако как? Не вручную же вбивать много разных данных в функции и смотреть, тот ли результат. Постойте, мы же с вами написали какую-то программу, а что нам мешает написать другую программу, которая будет тестировать первую? Специально для таких программ в стандартной библиотеке python есть модуль unittest.&lt;/p&gt;
  &lt;blockquote&gt;Код с подсветкой можете найти на Pastebin:&lt;/blockquote&gt;
  &lt;blockquote&gt;Файл с функцией: &lt;a href=&quot;https://pastebin.com/NH5FmLSc&quot; target=&quot;_blank&quot;&gt;https://pastebin.com/NH5FmLSc&lt;/a&gt;&lt;/blockquote&gt;
  &lt;blockquote&gt;Файл с тестами: &lt;a href=&quot;https://pastebin.com/BtqXuNiK&quot; target=&quot;_blank&quot;&gt;https://pastebin.com/BtqXuNiK&lt;/a&gt;&lt;/blockquote&gt;
  &lt;p&gt;Давайте напишем функцию для получения чисел Фибоначчи в файле, который назовём &lt;code&gt;fibonacci.py&lt;/code&gt;&lt;/p&gt;
  &lt;pre&gt;def get_fibonacci_numbers(amount):                        
  if amount == 1:                               
    return [1]                                
  result = [1, 1]                               
  for i in range(amount-2):                          
    result.append(result[-1] + result[-2])                  
  return result
&lt;/pre&gt;
  &lt;p&gt;Теперь напишем программу, которая будет тестировать эту функцию. Для этого в модуле unittest есть класс TestCase, от которого можно наследоваться и создавать тестирующей класс. У объекта этого класса есть специальные методы вида assert&amp;lt;что-то ещё&amp;gt;, которые сравнивают разные значения с ожидаемыми. Самым распространённым является метод assertEqual, который сравнивает 2 значения и, в случае различия, выдаёт ошибку. Давайте напишем самый простой тест для одного числа в файле &lt;code&gt;fibtest.py&lt;/code&gt;&lt;/p&gt;
  &lt;pre&gt;from unittest import TestCase                          
from fibonacci import get_fibonacci_numbers                   
                                         
                                         
class FibonacciTest(TestCase):                        
  def test_single(self):                            
    self.assertEqual(1, get_fibonacci_numbers(1)[0]) 
&lt;/pre&gt;
  &lt;p&gt;Мы создаём у этого класса тестирующий метод, название которого обязательно должно начинаться со слова test(требование программы-тестера). Давайте напишем ещё один тест посложнее, который будет проверять всю последовательность на каком-нибудь числе&lt;/p&gt;
  &lt;pre&gt;from unittest import TestCase                          
from fibonacci import get_fibonacci_numbers                   
                                         
                                         
class FibonacciTest(TestCase):                          
  def test_single(self):                            
    self.assertEqual(1, get_fibonacci_numbers(1)[0])             
                                         
  def test_big_number(self):                          
    big_number = 1337                            
    sequence = get_fibonacci_numbers(big_number)               
    self.assertEqual(1, sequence[0])                     
    self.assertEqual(1, sequence[1])                     
    for i in range(2, big_number):                      
      self.assertEqual(sequence[i-1] + sequence[i-2], sequence[i])  
&lt;/pre&gt;
  &lt;p&gt;Тесты есть, осталось их запустить. Для этого надо выполнить команду test из модуля unittest на нашем файле:&lt;/p&gt;
  &lt;pre&gt;python -m unittest test fibtest.py
&lt;/pre&gt;
  &lt;p&gt;Вывод у команды будет следующего вида:&lt;/p&gt;
  &lt;pre&gt;----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK
&lt;/pre&gt;
  &lt;p&gt;Статус OK говорит, что все тесты пройдены успешно. Если бы были ошибки, то там была бы информация о них. Вот так вот можно стандартными средствами тестировать программы.&lt;/p&gt;
  &lt;p&gt;Надеюсь, статья была вам полезной.&lt;/p&gt;
  &lt;p&gt;Буду рад видеть вас в группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:rJnA9jwEX</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/rJnA9jwEX?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Получаем число с Random.org API на Python</title><published>2018-07-26T20:10:59.658Z</published><updated>2018-07-26T20:10:59.658Z</updated><summary type="html">У многих веб-сервисов есть свой HTTP API - интерфейс, позволяющий обмениваться с их серверами данными. В этой статье разберёмся, как делать запросы из Python без сторонних библиотек. Рассматривать мы это будем на примере небезызвестного Random.org - теперь никто нас не упрекнёт, что рандом в нашей программе &quot;нечестный&quot;)</summary><content type="html">
  &lt;p&gt;У многих веб-сервисов есть свой HTTP API - интерфейс, позволяющий обмениваться с их серверами данными. В этой статье разберёмся, как делать запросы из Python без сторонних библиотек. Рассматривать мы это будем на примере небезызвестного Random.org - теперь никто нас не упрекнёт, что рандом в нашей программе &amp;quot;нечестный&amp;quot;)&lt;/p&gt;
  &lt;p&gt;Необходимая информация об API представлена по ссылке &lt;a href=&quot;https://api.random.org/json-rpc/1/&quot; target=&quot;_blank&quot;&gt;api.random.org&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Вот на &lt;a href=&quot;https://api.random.org/api-keys/beta&quot; target=&quot;_blank&quot;&gt;этой странице&lt;/a&gt; вы сможете получить токен для API - просто введите свой email и он придёт в письме.&lt;/p&gt;
  &lt;p&gt;Мы будем пользоваться самым базовым API методом - &lt;a href=&quot;https://api.random.org/json-rpc/1/basic&quot; target=&quot;_blank&quot;&gt;generateIntegers&lt;/a&gt;, который возвращает случайные числа от min до max.&lt;/p&gt;
  &lt;blockquote&gt;Полный код с подсветкой можете найти на &lt;a href=&quot;https://pastebin.com/1Y3F76HK&quot; target=&quot;_blank&quot;&gt;Pastebin&lt;/a&gt;&lt;/blockquote&gt;
  &lt;p&gt;Для начала, импортируем всё необходимое. А нужно нам немного: HTTPSConnection из http.client для того, чтобы отсылать запросы; dumps и loads из json чтобы кодировать и декодировать данные в JSON, который используется этим API.&lt;/p&gt;
  &lt;pre&gt;from http.client import HTTPSConnection                     
from json import dumps, loads                          
                                         
API_TOKEN = &amp;#x27;xxx&amp;#x27;# Ваш токен
&lt;/pre&gt;
  &lt;p&gt;Теперь давайте создадим словарь с данными для запроса и заголовками. Эти 2 словаря мы запакуем в JSON: теперь они готовы для отправки на сервер.&lt;/p&gt;
  &lt;pre&gt;&amp;quot;&amp;quot;&amp;quot;
Больше о формате запроса 
https://api.random.org/json-rpc/1/introduction
&amp;quot;&amp;quot;&amp;quot;
request_data = {  # Тело запроса                      
  &amp;#x27;jsonrpc&amp;#x27;: &amp;#x27;2.0&amp;#x27;,                              
  &amp;#x27;method&amp;#x27;: &amp;#x27;generateIntegers&amp;#x27;,                        
  &amp;#x27;params&amp;#x27;: {                                  
    &amp;#x27;apiKey&amp;#x27;: API_TOKEN,                           
    &amp;#x27;min&amp;#x27;: 1,  # Нижняя граница рандома                       
    &amp;#x27;max&amp;#x27;: 100,  # Верхняя граница        
    &amp;#x27;n&amp;#x27;: 1,  # Количество запрашиваемых чисел          
  },                                      
  &amp;#x27;id&amp;#x27;: 1,                                   
}                                        
encoded_data = dumps(request_data)                        
                                         
headers = {                                
  &amp;#x27;Content-Type&amp;#x27;: &amp;#x27;application/json-rpc&amp;#x27;,  # Тип запроса              
}                                        
encoded_headers = dumps(headers)  
&lt;/pre&gt;
  &lt;p&gt;Теперь непосредственно к обмену данными. Установим соединение и отправим данные:&lt;/p&gt;
  &lt;pre&gt;connection = HTTPSConnection(&amp;#x27;api.random.org&amp;#x27;)                  
connection.request(&amp;#x27;GET&amp;#x27;, &amp;#x27;/json-rpc/1/invoke&amp;#x27;, encoded_data, headers)  
&lt;/pre&gt;
  &lt;p&gt;Получим ответ и распакуем его из JSON:&lt;/p&gt;
  &lt;pre&gt;response = connection.getresponse()                       
response_data = loads(response.read().decode()) 
&lt;/pre&gt;
  &lt;p&gt;Если запрос прошёл успешно, то в response_data[&amp;#x27;result&amp;#x27;][&amp;#x27;random&amp;#x27;][&amp;#x27;data&amp;#x27;] будет лежать массив запрошенных чисел. Запрашивали мы одно число, его и выведем на экран.&lt;/p&gt;
  &lt;pre&gt;print(response_data[&amp;#x27;result&amp;#x27;][&amp;#x27;random&amp;#x27;][&amp;#x27;data&amp;#x27;][0])  
&lt;/pre&gt;
  &lt;p&gt;Вот так вот просто можно обмениваться данными с любым HTTP API, просто надо внимательно читать описания методов и формата, который требуется.&lt;/p&gt;
  &lt;p&gt;Жду вас в группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:rJt5hKEVm</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/rJt5hKEVm?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>lambda, map и filter в Python</title><published>2018-07-24T11:25:04.864Z</published><updated>2018-07-24T11:26:47.645Z</updated><summary type="html">&lt;img src=&quot;https://imageog.flaticon.com/icons/png/512/43/43146.png?size=1200x630f&amp;pad=10,10,10,10&amp;ext=png&amp;bg=FFFFFFFF&quot;&gt;Разберёмся с этими тремя элементами Python, которые очень часто применяются вместе, потому и были объединены мной в одну статью.</summary><content type="html">
  &lt;p&gt;Разберёмся с этими тремя элементами Python, которые очень часто применяются вместе, потому и были объединены мной в одну статью.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://imageog.flaticon.com/icons/png/512/43/43146.png?size=1200x630f&amp;pad=10,10,10,10&amp;ext=png&amp;bg=FFFFFFFF&quot; width=&quot;1200&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Первой я хочу рассмотреть конструкцию &lt;strong&gt;lambda&lt;/strong&gt;. Это способ определения анонимной функции(&amp;quot;лямбды&amp;quot;, как их ещё называют). Тут слово &amp;quot;анонимный&amp;quot; никак не связано с Роскомнадзором и сетью Tor, просто у таких функций нет имени. Постойте, а как к ним обращаться? А нам это и не нужно, мы хотим просто передать простенькую функцию как аргумент куда-нибудь и забыть про неё.&lt;/p&gt;
  &lt;p&gt;Объявляются такие функции следующим образом:&lt;/p&gt;
  &lt;pre&gt;lambda &amp;lt;аргументы&amp;gt;: &amp;lt;выражение&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;Например вот функция, которая возвращает куб данного числа:&lt;/p&gt;
  &lt;pre&gt;lambda x: x**3
&lt;/pre&gt;
  &lt;p&gt;Красиво, просто, пока непонятно зачем. Для примера обратимся к методу sort и сделаем сортировку по обратному значению(даже не спрашивайте зачем).&lt;/p&gt;
  &lt;pre&gt;a = [1, -2, 4, 5, 228, -322]
a.sort(key=lambda x: 1/x)  # [-2, -322, 228, 5, 4, 1]
&lt;/pre&gt;
  &lt;p&gt;Теперь перейдём к двум похожим, но разным функциям &lt;strong&gt;map&lt;/strong&gt; и &lt;strong&gt;filter&lt;/strong&gt;, в которые очень часто передают лямбда функции.&lt;/p&gt;
  &lt;p&gt;map принимает 2 аргумента: функцию и массив, и возвращает список(на самом деле специальный map объект), в котором ко всем элементам массива применили нашу функцию. Так как с map объектом мы ничего интересного сделать не можем, то его мы превратим обратно в список.&lt;/p&gt;
  &lt;pre&gt;a = [1, -2, 4, 5, 228, -322]
mapped = list(map(lambda x: x**2, a))  # Список квадратов чисел
&lt;/pre&gt;
  &lt;p&gt;filter принимает всё те же 2 аргумента и возвращает filter объект(который опять же мы превратим в список), в котором остались только те элементы, на которых функция истинна. Например:&lt;/p&gt;
  &lt;pre&gt;a = [1, -2, 4, 5, 228, -322]
filtered = list(filter(lambda x: x &amp;lt; 10, a))  # Список чисел меньше 10
&lt;/pre&gt;
  &lt;p&gt;Благодаря этим двум функциям и конструкции lambda можно сократить рутинный код до однострочника. Однако сильно увлекаться этим не стоит, а то рискуете сделать свою программу нечитаемой.&lt;/p&gt;
  &lt;p&gt;Больше статей в группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:rJidaa-Nm</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/rJidaa-Nm?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Пишем веб-сервер на Flask</title><published>2018-07-22T09:25:07.276Z</published><updated>2018-07-22T09:25:07.276Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/d5/d5e8b976-f2ee-4c00-a3db-73476fd8efd6.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://cdn.scotch.io/scotchy-uploads/2016/12/6bOQ3QNDTISElwCsEL0f_getting-started-with-flask.jpg&quot;&gt;В наше время, мало таких приложений, которые обходятся без обмена данными со своим сервером. Давайте разберём на пальцах, что представляет из себя этот самый &quot;сервер&quot; и даже напишем серверную программу на фреймворке Flask.</summary><content type="html">
  &lt;p&gt;В наше время, мало таких приложений, которые обходятся без обмена данными со своим сервером. Давайте разберём на пальцах, что представляет из себя этот самый &amp;quot;сервер&amp;quot; и даже напишем серверную программу на фреймворке Flask.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://cdn.scotch.io/scotchy-uploads/2016/12/6bOQ3QNDTISElwCsEL0f_getting-started-with-flask.jpg&quot; width=&quot;1200&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2&gt;Немного теории&lt;/h2&gt;
  &lt;p&gt;&amp;quot;Общение&amp;quot; с сервером представляет из себя цепочку &lt;strong&gt;запрос&lt;/strong&gt;-&lt;strong&gt;ответ&lt;/strong&gt;. Мы формируем запрос в специальном HTTP формате, потом отсылаем его на нужный адрес и получаем(или не получаем) ответ от сервера. У адреса есть 2 важные составляющие: &lt;strong&gt;домен&lt;/strong&gt; и &lt;strong&gt;метод&lt;/strong&gt;. Пример: &lt;code&gt;https://api.vk.com/method/messages.send&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Домен - https://api.vk.com - это то место в Сети, где располагается наш сервер. Всё, что обращается к нашему домену, будет обрабатываться нашим веб-сервером.&lt;/p&gt;
  &lt;p&gt;Метод - /method/messages.send - это &amp;quot;функция&amp;quot; нашего сервера, которую мы хотим использовать.&lt;/p&gt;
  &lt;h2&gt;Теперь к делу&lt;/h2&gt;
  &lt;blockquote&gt;Замечание: я пишу команды в консоли в предположении, что ваш интерпретатор называется python , если он называется иначе, то соответственно заменяйте это слово своим названием&lt;/blockquote&gt;
  &lt;p&gt;Нам понадобится Python и библиотека flask. Её можно установить следующим образом:&lt;/p&gt;
  &lt;pre&gt;python -m pip install flask
&lt;/pre&gt;
  &lt;p&gt;Теперь создадим файл &lt;em&gt;app.py &lt;/em&gt;, в котором и будет наша программа.&lt;/p&gt;
  &lt;p&gt;Для начала импортируем в нём модуль Flask из библиотеки flask и создадим объект нашего приложения:&lt;/p&gt;
  &lt;pre&gt;from flask import Flask

app = Flask(&amp;#x27;hello_world&amp;#x27;)
&lt;/pre&gt;
  &lt;p&gt;Теперь давайте допишем функцию, которая будет отвечать &amp;quot;Hello world!&amp;quot; на запрос к методу /hello_world&lt;/p&gt;
  &lt;pre&gt;from flask import Flask

app = Flask(&amp;#x27;hello_world&amp;#x27;)


@app.route(&amp;#x27;/hello_world&amp;#x27;)
def hello():
	return &amp;quot;Hello world!&amp;quot;
&lt;/pre&gt;
  &lt;p&gt;Вы можете мне не поверить, но это всё. Теперь давайте запустим нашу программу у себя на компьютере(используя его как сервер).&lt;/p&gt;
  &lt;pre&gt;python -m flask run --port 8000
&lt;/pre&gt;
  &lt;p&gt;Зайдите теперь в браузер по адресу &lt;a href=&quot;http://127.0.0.1:8000/hello_world&quot; target=&quot;_blank&quot;&gt;http://127.0.0.1:8000/hello_world&lt;/a&gt; и увидите ту самую строчку. 127.0.0.1 - специальный домен, который отображает наш с вами компьютер, а 8000 - порт нашего подключения.&lt;/p&gt;
  &lt;p&gt;Эта статья была написана чтобы показать, что веб-сервер - не что-то &amp;quot;волшебное&amp;quot; и очень сложное, а самая обычная программа, к которой мы обращаемся специальным образом. Возможно вы заинтересуетесь темой, тогда вам стоит начать изучать Backend разработку.&lt;/p&gt;
  &lt;p&gt;До встреч в группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:rJ5kiJA7m</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/rJ5kiJA7m?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Форматирование строк в Python</title><published>2018-07-19T10:42:31.815Z</published><updated>2018-07-19T10:42:31.815Z</updated><summary type="html">Очень часто, вывод программы представляет из себя некую строку, в которой содержатся данные из вашей программы. Здесь мы рассмотрим способы форматирования строк, то есть подстановки ваших переменных в строки в языке программирования Python.</summary><content type="html">
  &lt;p&gt;Очень часто, вывод программы представляет из себя некую строку, в которой содержатся данные из вашей программы. Здесь мы рассмотрим способы форматирования строк, то есть подстановки ваших переменных в строки в языке программирования Python.&lt;/p&gt;
  &lt;h2&gt;C-форматирование&lt;/h2&gt;
  &lt;p&gt;Наверное все, кто программировал на языке C или C++ знают о такой функции, как printf, которая выводит строку, подставляя туда переменные в нужном формате. Чтобы понять о чём я говорю, рассмотрим примеры:&lt;/p&gt;
  &lt;pre&gt;printf(&amp;quot;Целое число %d&amp;quot;, 5);
printf(&amp;quot;Дробное число %f&amp;quot;, 2.1);
printf(&amp;quot;Строка %s&amp;quot;, &amp;quot;какая-то строка&amp;quot;);
&lt;/pre&gt;
  &lt;p&gt;Для каждого типа данных есть собственная последовательность + есть всякие модификаторы. Побольше о них можно узнать например &lt;a href=&quot;https://ru.wikipedia.org/wiki/Printf&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt;. Для того, чтобы таким образом отформатировать строку, используется следующий синтаксис:&lt;/p&gt;
  &lt;p&gt;&amp;lt;строка с параметрами&amp;gt;%(&amp;lt;переменные для подстановки&amp;gt;)&lt;/p&gt;
  &lt;p&gt;Например:&lt;/p&gt;
  &lt;pre&gt;print(&amp;quot;%d %f %s&amp;quot;%(1, 2.5, &amp;quot;string&amp;quot;)) # Вывод: 1 2.500000 string
&lt;/pre&gt;
  &lt;p&gt;Можно записать строку в переменную и потом подставить параметры:&lt;/p&gt;
  &lt;pre&gt;pattern = &amp;quot;%d %f %s&amp;quot;
print(pattern%(2, 3.3, &amp;quot;abc&amp;quot;))  # Вывод: 2 3.300000 abc
&lt;/pre&gt;
  &lt;p&gt;Этот способ хорош тем, что можно очень гибко настраивать параметры вывода при помощи модификаторов. Например вот так можно вывести число с точностью 3 знака после запятой:&lt;/p&gt;
  &lt;pre&gt;print(&amp;quot;%.3f&amp;quot;%(2.12345))  
&lt;/pre&gt;
  &lt;h2&gt;Метод format&lt;/h2&gt;
  &lt;p&gt;У строк есть специальный метод format, который выполняет ту же задачу, но немного элегантнее. Он ищет в строке фигурные скобки и подставляет вместо них аргумент. В фигурных скобках можно указать номер аргумента(нумеруются с 0), а можно ничего не указывать и format подставит аргументы по порядку.&lt;/p&gt;
  &lt;p&gt;Пример:&lt;/p&gt;
  &lt;pre&gt;pattern = &amp;quot;{}:{}:{}&amp;quot;
print(pattern.format(1, 2, 3))  # 1 2 3
another_pattern = &amp;quot;{2}:{1}:{0}&amp;quot;
print(another_pattern.format(1, 2, 3))  # 3 2 1
&lt;/pre&gt;
  &lt;p&gt;Этот способ хорош тем, что ему не важен тип аргумента, лишь их порядок.&lt;/p&gt;
  &lt;h2&gt;f-строки&lt;/h2&gt;
  &lt;p&gt;С версии 3.6 существует ещё один способ форматирования. Он очень удобен, однако не без недостатков: подставляет аргументы в строку сразу при объявлении. Рассмотрим пример:&lt;/p&gt;
  &lt;pre&gt;a = 3
b = 2
print(f&amp;quot;{a*b} {a+b} {3*3}&amp;quot;)  # 6 5 9
&lt;/pre&gt;
  &lt;p&gt;Перед строкой ставится префикс f, который обозначает f-строку.Внутри могут быть любые выражения в фигурных скобках: они вычисляются сразу же.&lt;/p&gt;
  &lt;p&gt;Какой из этих способов использовать зависит от вас и от ситуации. В любом случае, один из них точно подойдёт. А эта статья подошла к концу, до встреч в группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;.&lt;/p&gt;

</content></entry><entry><id>snakeblog:r1K3mtnmm</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/r1K3mtnmm?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Декораторы</title><published>2018-07-18T09:26:52.965Z</published><updated>2018-07-18T11:24:34.445Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/d0/d0f78feb-53fc-4245-bfc4-b84d6bdd45bd.png"></media:thumbnail><summary type="html">&lt;img src=&quot;http://udc-razvitie.com/wp-content/uploads/2015/09/%D0%B4%D0%B8.jpg&quot;&gt;Давайте предположим, что у нас есть несколько функций, которые что-то выводят, скажем, логи нашей программы.</summary><content type="html">
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;http://udc-razvitie.com/wp-content/uploads/2015/09/%D0%B4%D0%B8.jpg&quot; width=&quot;720&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Давайте предположим, что у нас есть несколько функций, которые что-то выводят, скажем, логи нашей программы.&lt;/p&gt;
  &lt;pre&gt;from datetime import datetime                          
                                         
                                         
def date_logger(): # Выводит текущую дату и время                
  print(datetime.now().strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;))             
                                         
                                         
def connection_logger(connected): # Выводит статус соединения          
  if connected:                                
    print(&amp;quot;Connected&amp;quot;)                            
  else:                                    
    print(&amp;quot;Not connected&amp;quot;)
&lt;/pre&gt;
  &lt;p&gt;Мы где-то используем их в коде. Всё хорошо, но тут заказчик говорит, что перед каждым логом надо выводить &amp;quot;Log:&amp;quot;. Зачем? А кто знает, надо и надо.&lt;/p&gt;
  &lt;p&gt;Конечно можно в начале каждой функции выводить это слово. Однако функций может быть много, а завтра заказчик захочет выводить другое слово. Хочется чего-то более универсального. Тут кто-то предложит глобальную переменную, но это не всегда лучший способ. Сегодня я вам расскажу про другой метод решения этой проблемы и имя ему декоратор.&lt;/p&gt;
  &lt;p&gt;Давайте рассмотрим следующую функцию - декоратор, которая &amp;quot;оборачивает&amp;quot; другую функцию:&lt;/p&gt;
  &lt;pre&gt;def log_decorator(function):
    def wrapped(*args):  # Вложенная функция-обёртка
        print(&amp;quot;Log:&amp;quot;, end=&amp;#x27; &amp;#x27;)
        function(*args)  # Вызываем нашу функцию с параметрами
    return wrapped 
&lt;/pre&gt;
  &lt;p&gt;А теперь давайте заменим наши функции на обёрнутые этой.&lt;/p&gt;
  &lt;pre&gt;date_logger = log_decorator(date_logger)
connection_logger = log_decorator(connection_logger)
&lt;/pre&gt;
  &lt;p&gt;Действительно, теперь, при вызове будет выводиться &amp;quot;Log: &amp;quot;. Казалось бы, проблема решена. Но как-то не эстетично это выглядит. Поэтому в питоне есть специальный синтаксис для декорации:&lt;/p&gt;
  &lt;pre&gt;@&amp;lt;имя декоратора&amp;gt;
def &amp;lt;декорируемая функция&amp;gt;(...):
	...
&lt;/pre&gt;
  &lt;p&gt;То есть наши функции будут выглядеть следующим образом:&lt;/p&gt;
  &lt;pre&gt;@log_decorator
def date_logger():  # Выводит текущую дату и время
	print(datetime.now().strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;))

@log_decorator
def connection_logger(connected): # Выводит статус соединения
	if connected:
		print(&amp;quot;Connected&amp;quot;)
	else:
		print(&amp;quot;Not connected&amp;quot;)
&lt;/pre&gt;
  &lt;p&gt;Отлично, но что, если я хочу сделать декоратор с параметром? Здесь надо создать функцию с параметром, которая будет возвращать декоратор. Например так:&lt;/p&gt;
  &lt;pre&gt;def word_log_decorator(word):
   def decorator(function):
       def wrapped(*args):
           print(word, end=&amp;#x27;: &amp;#x27;)
           function(*args)
       return wrapped
   return decorator
&lt;/pre&gt;
  &lt;p&gt;Вызывать эту функцию мы будем при декорации следующим образом:&lt;/p&gt;
  &lt;pre&gt;@word_log_decorator(&amp;quot;Log&amp;quot;)
def date_logger():  # Выводит текущую дату и время
    print(datetime.now().strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;))
&lt;/pre&gt;
  &lt;p&gt;При помощи декораторов ваш код может стать более понятным, однако стоит различать, когда имеет смысл поменять саму функцию, а когда написать декоратор.&lt;/p&gt;
  &lt;p&gt;Надеюсь, статья была вам полезной.&lt;/p&gt;
  &lt;p&gt;Надеюсь увидеть вас в моей группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>snakeblog:S1a9As_7Q</id><link rel="alternate" type="text/html" href="https://teletype.in/@snakeblog/S1a9As_7Q?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=snakeblog"></link><title>Генераторы</title><published>2018-07-15T11:45:07.681Z</published><updated>2018-07-15T12:17:03.338Z</updated><summary type="html">В этой статье я хочу рассказать о такой интересной особенности Python, которой нет во многих других языках, и которая носит название &quot;генераторы&quot;. Что, если я вам скажу, что вот такой код, при некоторых условиях, может выполняться до бесконечности?</summary><content type="html">
  &lt;p&gt;В этой статье я хочу рассказать о такой интересной особенности Python, которой нет во многих других языках, и которая носит название &amp;quot;генераторы&amp;quot;. Что, если я вам скажу, что вот такой код, при некоторых условиях, может выполняться до бесконечности?&lt;/p&gt;
  &lt;pre&gt;for number in fibonacci_numbers:
	print(number)
&lt;/pre&gt;
  &lt;p&gt;Наверное у вас появится закономерный вопрос: &amp;quot;Как же так, ведь fibonacci_numbers должен быть ограничен по длине и когда-нибудь цикл закончится?&amp;quot;. И вы были бы правы, будь эта переменная списком или чем-то подобным, но в примере выше, она - генератор и не имеет конца. Заинтересовались? Тогда давайте разберёмся, как работает эта сущность в Python.&lt;/p&gt;
  &lt;p&gt;Для начала, поймём, как работает цикл &lt;strong&gt;for&lt;/strong&gt;. На самом деле, всё, что он делает:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Вызывает на нашем объекте &amp;quot;магический&amp;quot; метод&lt;strong&gt; __iter__&lt;/strong&gt; и получает специальный объект-итератор, у которого есть метод &lt;strong&gt;__next__&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;При каждой итерации, этот метод вызывается и значение переменной, указанной нами в цикле обновляется.&lt;/li&gt;
    &lt;li&gt;Итерация прекращается, когда метод&lt;strong&gt; __next__&lt;/strong&gt; вызывает исключение StopIteration.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;То есть, мы можем сделать генератор своими руками. Прикрепляю ссылку на Pastebin потому что там есть подсветка синтаксиса и копировать код оттуда проще.&lt;/p&gt;
  &lt;p&gt;&lt;a href=&quot;https://pastebin.com/sFd0CT3a&quot; target=&quot;_blank&quot;&gt;Код на Pastebin&lt;/a&gt;&lt;/p&gt;
  &lt;pre&gt;class FibonacciGenerator:                            
  &amp;quot;&amp;quot;&amp;quot;                                     
  Класс, объект которого мы будем создавать                  
  &amp;quot;&amp;quot;&amp;quot;                                     
  class FibonacciIterator:                           
    &amp;quot;&amp;quot;&amp;quot;                                   
    Вспомогательный класс, который реализует метод __next__         
    Этот метод вызывается на каждой итерации for               
    &amp;quot;&amp;quot;&amp;quot;                                   
    def __init__(self):                           
      &amp;quot;&amp;quot;&amp;quot;                                 
      Начинаем нашу последовательность с двух единиц            
      &amp;quot;&amp;quot;&amp;quot;                                 
      self.first_number = 1                        
      self.second_number = 1                        
      self.iterations = 0                         
                                         
    def __next__(self):                           
      self.iterations += 1                         
      if self.iterations &amp;lt;= 2: # Первые 2 раза мы возвращаем единицу     
        return 1                             
      self.first_number, self.second_number = self.second_number, self.first_number + self.second_number
      return self.second_number                      
                                         
  def __iter__(self):                             
    return self.FibonacciIterator()                     
                                         
fib_gen = FibonacciGenerator()                          
for i in fib_gen:                                
  print(i)
&lt;/pre&gt;
  &lt;p&gt;Если вы запустите у себя этот код, то увидите бесконечно выводящиеся числа Фибоначи. Теперь о том, как это работает: for, когда начинает свою работу, вызывает метод &lt;strong&gt;__iter__&lt;/strong&gt; и получает объект класса FibonacciIterator. На нём, перед каждой итерацией, он запускает метод &lt;strong&gt;__next__&lt;/strong&gt; и получает следующее число, которое записывается в переменную i. Согласитесь, выглядит не очень красиво.Наверное поэтому в Python существует специальный синтаксис, призванный упростить создание генераторов. Главным средством для этого, является ключевое слово &lt;strong&gt;yield&lt;/strong&gt;. Это как &lt;strong&gt;return&lt;/strong&gt;, но функция не заканчивается, а её состояние запоминается и при вызове &lt;strong&gt;__next__&lt;/strong&gt; продолжается с того же места. Пример с числами Фибоначи:&lt;/p&gt;
  &lt;p&gt;&lt;a href=&quot;https://pastebin.com/h920Ji4M&quot; target=&quot;_blank&quot;&gt;Код на Pastebin&lt;/a&gt;&lt;/p&gt;
  &lt;pre&gt;def fibonacci_generator():                            
  &amp;quot;&amp;quot;&amp;quot;                                     
  Эта функция возвращает специальный объект-генератор               
  &amp;quot;&amp;quot;&amp;quot;                                     
  yield 1                                   
  yield 1                                   
  first, second = 1, 1                             
  while True:                                 
    first, second = second, first + second                  
    yield second                               
                                         
test_generator = fibonacci_generator()                      
for i in test_generator:                             
  print(i)
&lt;/pre&gt;
  &lt;p&gt;Эта программа делает всё то же самое. test_generator - объект специального класса generator, который реализует то, что мы описали. Кроме &lt;strong&gt;yield&lt;/strong&gt; есть ещё конструкция &lt;strong&gt;yield from&lt;/strong&gt; &amp;lt;collection&amp;gt;, которая делает yield последовательно каждого элемента &amp;lt;collection&amp;gt;. Выглядит это так:&lt;/p&gt;
  &lt;pre&gt;def yield_from_generator():
	yield from (1,2,3)
&lt;/pre&gt;
  &lt;p&gt;Объект, созданный этой функцией вернёт 1, потом 2, потом 3.&lt;/p&gt;
  &lt;p&gt;Бонус:&lt;/p&gt;
  &lt;p&gt;У генераторов есть сокращённый синтаксис, как в list comprehensions, но вместо квадратных скобок надо поставить круглые. Например вот генератор квадратов чисел от 1 до 100:&lt;/p&gt;
  &lt;pre&gt;(i**2 for i in range(1, 101))
&lt;/pre&gt;
  &lt;p&gt;Генераторы - очень мощный инструмент, который может, при правильном применении, сильно упростить код. Используйте с умом и наслаждайтесь красотой и мощью Python!&lt;/p&gt;
  &lt;p&gt;До новых встреч в группе &lt;a href=&quot;https://vk.com/snakeblog&quot; target=&quot;_blank&quot;&gt;SnakeBlog&lt;/a&gt;&lt;/p&gt;

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