Глава 1. Обзор комплекта протокола TCP/IP и языка Python

Данная книга предполагает что у вас имеется определённое понимание сетевых протоколов и самого языка Python. По моему опыту типичный системный или сетевой инженер и разработчик может не помнить в точности конечный автомат TCP на повседневной основе (я точно знаю что нет), но он/ она должны бы быть знакомы с базовыми понятиями самой модели OSI, имеющихся операций TCP и UDP, заголовков IP и многого такого.

Данная глава выполнит очень краткий обзор по всем относящимся к теме сетевым вопросам. В том же самом обзоре мы также предпримем повтор самого языка Python на высоком уровне, достаточного чтобы читатели, которые не кодировали регулярно на Python могли иметь хорошую основу для того чтобы пройтись по оставшейся части данной книги.

В частности, мы рассмотрим следующие темы:

  • Обзор всемирного Интернета

  • Модель OSI и клиент- сервер

  • Комплект протоколов TCP, UDP, IP

  • Синтаксис, типы, операторы и циклы Python

  • Расширение Python с помощью функций, классов и пакетов

Не беспокойтесь если вам кажется, что вам потребуется дополнительная информация, так как я не думаю что представленная в данной главе информация является исчерпывающей. Ознакомьтесь со справочной информацией имеющегося в данной главе раздела для того чтобы прочитать дополнительно о представляющих вам интерес темам.

Обзор Интернета

Что такое интернет? На этот казалось бы простой вопрос можно получить различные ответы в зависимости от вашего контекста. Для различных людей интернет означает различные вещи, молодые, в возрасте, студенты, учителя, люди от бизнеса, поэты, все могут иметь собственный ответ на этот вопрос.

Для некоторого сетевого инженера и системного инженера по развитию, всемирный интернет является некоторой глобальной компьютерной сетью, предоставляющей разнообразную информацию. Данная система глобальной вычислительной сети на самом деле может представлять некую паутину межсетевого соединения в одно целое больших и малых сетевых сред. Представим себе вашу домашнюю сетевую среду; она будет состоять из некоторого домашнего коммутатора, соединяющего ваши смартфоны, планшеты, компьютеры и телевизоры между собой с тем, чтобы они взаимодействовали друг с другом. Затем, когда им необходимо осуществить соединения с внешним миром, они передают свою информацию на домашний маршрутизатор чтобы связать вашу домашнюю сетевую среду с некоторой большой сетью, обычно имеющую уместное название поставщика интернет- услуг (ISP, Internet Service Provider). Ваш ISP зачастую состоит из концевых узлов, которые собирают весь обмен в свою центральную сетевую среду (ядро). Функцией такой сети ядра является организация межсетевого взаимодействия таких пограничных сетевых сред через некую более высокоскоростную сетевую среду. Через специализированные оконечные узлы ваш ISP соединяется с прочими ISP для передачи вашего обмена в соответствии с вашим назначением. Обратный путь от вашего назначения в ваш домашний компьютер, планшет, или смартфон может совпадать, а может и нет с тем же самым путём, через все эти сетевые среды обратно к вашему экрану.

Давайте взглянем на те компоненты, которые составляют данную паутину сетевых сред.

Серверы, хосты и сетевые компоненты

Хосты (hosts) являются оконечными узлами в сетевых средах, которые взаимодействуют с прочими узлами. В сегодняшнем мире некий хост может быть конкретным обычным компьютером, либо может быть вашим смартфоном, планшетом или телевизором. С восхождением IoT (Internet of Things, Интернета вещей), наше широкое определение хоста может быть расширено чтобы включать IP камеру, коробки ТВ- наборов, а также всё растущего типа датчиков, которые мы можем применять в сельском хозяйстве, на фабриках, в автомобилях и тому подобном. При таком взрывообразном росте общего числа хостов, подключаемых во всемирный Интернет, все они нуждаются в адресации, маршрутизации и управлении, а спрос на соответствующую сетевую среду никогда не был более значительным.

Большую часть времени когда мы находимся во всемирном Интернете, мы запрашиваем службы. Такая служба может быть некоей веб страницей, отправкой и приёмом электронных писем, передачей файлов и тому подобного. Эти службы предоставляются серверами. Как и подразумевает само название, они предоставляют службы для множества узлов и поэтому обычно имеют более высокие уровни аппаратной спецификации. В некотором смысле, серверы представляют собой особые суперузлы в имеющейся сетевой среде, которые предоставляют дополнительные возможности своим одноранговым партнёрам. Позже в разделе клиент- сервер мы рассмотрим серверы.

Если представить себе серверы и хосты как о городах и посёлках, тогда сетевые компоненты являются нашими дорогами и шоссе для их соединения. На самом деле, при описании сетевых компонентов, которые повсеместно передают всё растущие в размерах биты и байты, на ум приходит термин "информационной супермагистрали". В модели OSI, которой мы коснёмся, такие сетевые компоненты являются маршрутизаторами и коммутаторами, которые располагаются на втором и третьем уровнях данной модели, помимо уровня оптиковолоконного кабеля, коаксиального кабеля, витых медных пар и некоторого оборудования DWDM (уплотнения по длине волны высокой плотности, Dense Walelength Division Multiplexing), которые можно привести в качестве некоторых примеров.

Всё это вместе, хосты, серверы, а также сетевые компоненты создают всемирный Интернет, который мы знаем сегодня.

Появление центров обработки данных

В своём последнем разделе мы рассмотрели различные роли, которые серверы, хосты и сетевые компоненты играют в межсетевом взаимодействии. Из- за того, что такими серверами требуется высокая ёмкость оборудования, они часто все вместе помещаются в неком централизованном расположении с тем, чтобы ими можно было более эффективно управлять. Мы будем называть такие расположения ЦОД (Центрами обработки данных, DC - datacenters).

Корпоративные центры обработки данных

В обычной корпорации, определённая компания, как правило, нуждается во внутренних инструментах, таких как электронная почта, хранилище документов, отслеживание продаж, выписка счетов, инструменты управления людскими ресурсами, а также межсетевое совместное владение знаниями. Эти термины транслируются в файловые и почтовые серверы, серверы баз данных, а также веб серверы. В отличии от компьютеров пользователей, это обычно высококлассные компьютеры, которым необходимо усиленные энергоснабжение, отвод тепла и сетевые соединения. Неким сопутствующим элементом данного оборудования также является определённый объём производимого ими шума. Обычно они централизованно размещаются в некотором расположении, называемом MDF (Main Distribution Frame, Основной структурой распределения) в данной корпорации для предоставления необходимого электропитания, его дублирования, охлаждения и сетевой скорости.

Для соединения с MDF, весь пользовательский обмен обычно собирается в некотором месте, которое иногда именуется IDF (Intermediate Distribution Frame, Промежуточной структурой распределения), прежде чем выполнить соединение с MDF. Нет ничего необычного в том, что IDF- MDF распространяется следуя за физическим размещением всех зданий или кампуса корпорации. Например, каждый этаж здания может представлять некий IDF, который объединяется с MDF на другом этаже. Если ваша корпорация состоит из ряда зданий, дальнейшее объединение может быть выполнено путём соединения обмена таких зданий, прежде чем соединять их с ЦОД корпорации.

ЦОД корпорации обычно следует трём уровням: доступа, распределения и ядра. Уровень доступа аналогичен портам для подключения каждого пользователя; IDF можно рассматривать как уровень распределения, в уровень ядра состоит из таких соединений с самим MDF и самих корпоративных ЦОД. Это, конечно, некое упрощение корпоративных сетевых сред, поскольку некоторые из них не будут следовать одной и той же модели.

Облачные центры обработки данных

с появлением облачных вычислений и программного обеспечения или инфраструктуры как некоторой службы (SaaS, IaaS), мы можем сказать, что такие поставщики облачных ЦОД строят облачные ЦОД. Из- за общего числа размещаемых серверов они обычно требуют большого, очень большого объёма энергоснабжения, отвода тепла и сетевых скоростей и нагрузок чем любой корпоративный ЦОД. На самом деле такие облачные ЦОД являются настолько крупными, что они обычно строятся вплотную к источникам энергоснабжения, где они могут получать наинизшую стоимость электричества без существенных потерь на его транспортировку. Они также могут творчески подходить к вопросу отвода тепла в тех местах, где ЦОД может быть построен в обычно прохладном климате и поэтому они могут просто открыть все двери и окна чтобы поддерживать работу сервера при безопасной температуре {Прим. пер.: и выращивать в заполярье кокосы и апельсины}. Любая из поисковых систем может снабдить вас поражающими воображения значениями, когда дело доходит до науки построения и управления такими облачными ЦОД для таких представителей как Amazon, Microsoft, Google и Facebook:

 

Рисунок 1


ЦОД в Юте (источник)

Службы, которые должны предоставлять данные серверы в ЦОД обычно не являются эффективными для размещения в каком- либо отдельно взятом сервере. Они распределяются по некоторой флотилии серверов, причём порой по множеству различных стоек для предоставления резервирования и гибкости для владельцев служб. Требования к латентности и резервированию оказывают гигантское воздействие на имеющуюся сетевую среду. Общее число взаимодействий устанавливает эквивалентность взрывному росту сетевого оборудования; это транслируется в то общее число раз, которое данное сетевое оборудование должно быть разведено по стойкам, подготовлено и как им управлять.

 

Рисунок 2


Сеть CLOS (источник)

В некотором смысле облачный ЦОД это именно то место, в котором становится необходимой автоматизация сетевой среды. Если мы следуем обычным способом управления сетевыми устройствами через некий терминал или интерфейс командной строки, общее число требуемых часов обслуживания не позволит данной службы быть доступной в разумном объёме времени. Это даже не говоря о том, что повторы людьми имеют склонность к ошибкам, отсутствию эффективности и ужасной растратой способностей инженеров.

Именно в облачном ЦОД автор начал свой путь сетевой автоматизации с помощью Python какое- то число лет тому назад и никогда не оглядывался назад с тех пор.

Граничные центры обработки данных

Если у нас имеется достаточная вычислительная мощность на уровне нашего ЦОД зачем что- то хранить в других местах помимо этих ЦОД? Все соединения будут перенаправлены на тот сервер, который предоставляет данную услугу, и мы можем считать вопрос закрытым. Ответ, естественно, зависит от варианта применения. Самое основное ограничение в отправке назад в свой ЦОД всех запросов и сеансов заключается в вводимых имеющимся транспортом задержках. Другими словами, сетевая среда является бутылочным горлышком. Как бы быстро не перемещался свет в вакууме, его задержка всё же не равняется нулю. В реальном мире задержка намного выше, когда пакеты перемещаются по множеству сетевых сред, а иногда и в кабелях по дну океанов, медленным спутниковым соединениям, сотовым связям 3G или 4G, либо Wi-Fi соединениям.

Решение? Уменьшить общее число сетевых сред, которое конечный пользователь должен преодолеть, причём по возможности до одной единственной. Будьте настолько близки к своему пользователю, насколько это возможно; и во- вторых: поместите достаточные ресурсы на границе своего местоположения. Представим, что вы строите службу видеопотока следующего поколения. Чтобы удовлетворить возросшему требованию пользователя в гладкости потока, вам захочется разместить такой сервер видео настолько близко к своему пользователю, насколько это возможно, если даже не внутри или просто рядом с ISP данного потребителя. Помимо этого, такой восходящий поток моей фабрики видео сервера был бы не просто соединён с одним или двумя ISP, но все такие ISP, к которым я могу подключиться с настолько большой полосой пропускания, которая потребуется. Именно это послужило к возникновению одноранговых пограничных ЦОД обмена данными больших ISP и поставщиков контента. Даже когда общее число сетевых устройств не настолько велико как в облачных ЦОД, они также могут получить преимущества от привнесения сетевой автоматизации в отношении увеличения безопасности и автоматизации визуализации. В последующих главах данной книги мы обсудим безопасность и визуализацию.

Модель OSI

Никакая книга по сетям не кажется полной, если она не пройдётся по модели OSI (Open System Interconnection, взаимодействия открытых систем). Данная модель является концептуальной, которая представляет в виде компонентов все функции телекоммуникаций в виде различных уровней. Данная модель определяет семь уровней, причём каждый уровень располагается непосредственно поверх другого, по мере того как они последовательно определяют структуры и характеристики. Например, имеющийся сетевой (network) уровень, такой как IP, может располагаться поверх различных типов канальных (data link) уровней, таких как Ethernet или ретрансляции кадров (frame relay). Эталонная модель OSI является хорошим способом для нормализации различных и отличающихся технологий в некий набор единого языка, на котором люди способны договариваться. Это значительно снижает сферу для участников, работающих на определённых индивидуальных уровнях и позволяет им углубляться в свои специфические задачи не беспокоясь о совместимости:

 

Рисунок 3


Модель ISO первоначально была разработана в конце 1970х и позже была опубликована совместно ISO (International Organization for Standardization) и теперь называемым Telecommunication Standardization Sector из ITU-T (Telecommunication StandardizationSector of the International Telecommunication Union). Она повсеместно применяется и обычно упоминается при введении новой темы в области телекоммуникаций.

Примерно в тот же самый период времени, когда была разработана модель OSI, приобрёл очертания всемирный Интернет. Обозначение, под которым обычно используется данная модель, обозначается как модель TCP/IP, поскольку TCP (Transmission Control Protocol) и IP (Internet Protocol), так как первоначально именно они составляли комплект данного протокола. Они несколько похожи на саму модель OSI в отношении того как они подразделяют сквозную передачу данных на уровни абстракции. Что их различает, так это то, что данная модель объединяет уровни с 5 по 7 в модели OSI в общий уровень Application (Приложений), в то время как уровни Physical и Data link (физический и канальный) соединены в общий канальный (Link) уровень {Прим. пер.: оставляя на месте слегка переименованные сетевой (Transport) и транспортный (Transport), всего - 4 уровня}:

 

Рисунок 4


Комплект протокола интернет (источник

Обе модели и OSI, и TCP/IP полезны при снабжении некоторого стандарта для представления повсеместного взаимодействия данных. Однако, по большей части мы будем ссылаться именно на модель TCP/IP, во многом по той причине, что именно на ней был построен всемирный Интернет. Мы будем определять модель OSI когда это необходимо, например, когда мы обсуждаем в последующих главах всю структуру веб.

Модели клиент- сервер

Эталонные модели демонстрируют некий стандартный способ для взаимодействия данных между двумя узлами. Конечно, сегодня мы знаем, что не все узлы создаются эквивалентными. Даже в свои дни DARPA-net имелись узлы рабочих станций, а также имелись узлы для целей обслуживания содержимого другим узлам. Такие модули обычно имеют спецификации более высокого уровня и более пристально обслуживаются их инженерами. Так как эти узлы предоставляют ресурсы и службы прочим, они обычно называются серверами. Такие серверы обычно пребывают в состоянии покоя ожидая инициирующих запросов от клиентов для выдачи своих ресурсов. Такая модель распределённых ресурсов, которые "запрашиваются" клиентами обычно имеет название модели Клиент - Сервер.

Почему это важно? Если вы на минутку задумаетесь о ней, вся важность сетевой среды основывается в действительности на данной модели Клиент- Сервер. Без неё на самом деле не было бы большой потребности в межсетевом взаимодействии. Именно оно требуется для обмена битами и байтами между клиентом и сервером и именно оно освещает своим светом всю важность сетевой инженерии. Конечно, мы все в курсе того как самая большая из всех сеть, всемирный Интернет, преобразовала все наши жизни и продолжает делать это вновь и вновь.

Вы спросите как каждый узел определяет своё время, скорость, источник и получателя всякий раз, когда им потребуется взаимодействовать друг с другом? Это вплотную подводит нас к понятию сетевых протоколов.

Комплекты сетевого протокола

В ранние дни работы с вычислительными сетями все протоколы имели частных владельцев и тщательно управлялись теми компаниями, которые разработали данный метод соединения. Если вы применяете в своих хостах протокол Novell IPX/SPX, вы не сможете взаимодействовать с хостами Apple AppleTalk и наоборот. Такие имеющие частных владельцев комплекты протоколов обычно имеют сопоставимые уровни в эталонной модели OSI и следуют методу взаимодействия клиент- сервер. Они обычно великолепно работают в LAN (Local Area Networks, локальных сетевых средах), которые закрыты и не имеют необходимости взаимодействовать со своим внешним миром. Когда в действительности их обмену необходимо выходить за рамки локальной сети, обычно для трансляции из одного протокола в другой, например из AppleTalk в IP, обычно применяется некое устройство межсетевого взаимодействия, такого как маршрутизатор. Такая трансляция обычно не очень привлекательна, но поскольку большая часть взаимодействий выполняется внутри имеющейся LAN, это можно терпеть.

Однако, по мере роста потребности в межсетевом общении, становится более значимой потребность в стандартизации используемых сетевых протоколов. такие протоколы частных владельцев со временем уступили место имеющимся комплектам стандартизованных протоколов TCP, UDP и IP, которые значительно расширили имеющиеся возможности из одной сети общаться с другой. Всемирный Интернет, самая большая из всех имеющихся сетей, для надлежащей работы полагается на данные протоколы. В нескольких последующих разделах мы рассмотрим каждый из этих комплектов протоколов.

TCP

TCP (Transmission Control Protocol, протокол управления передачей) является одним из самых основных протоколов, применяемых в нашем современном интернете. Если вы открыли некую веб страницу или отправили какое- то электронное письмо, вы прошли по сети при помощи протокола TCP. Данный протокол располагается на 4 уровне модели OSI и он отвечает за доставку всех сегментов данных между двумя узлами надёжным образом с проверкой на наличие ошибок. Сам TCP состоит из заголовка в 160 бит, содержащего помимо прочего порт источника и получателя, последовательный номер, номер подтверждения, управляющие флаги и контрольную сумму:

 

Рисунок 5


Заголовок TCP (источник

Функции и характеристики TCP

TCP использует сокеты дейтаграмм или порты для установления соединения хост- хост. Орган стандартизации, имеющий название IANA (Internet Assigned Numbers Authority, Комитет по цифровым адресам в интернете), назначает широко известные порты для указания определённых служб, такие как порт 80 для HTTP (веб) и порт 25 для SMTP (почта). Имеющийся сервер в модели клиент- сервер обычно ожидает (listen) на одном из таких широко известных портов приёма запросов на взаимодействие от своего клиента. Такое соединение TCP управляется самой операционной системой через имеющийся сокет, который представляет собой локальную оконечную точку для соединения.

Операции этого протокола составляют некий конечный автомат, которому необходимо отслеживать ожидание входящего соединения, прохождения сеанса взаимодействия, а также освобождение ресурсов при закрытии данного соединения. Каждое соединение TCP проходит через последовательность состояний таких как Listen, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT и CLOSED.

Сообщения TCP и обмен данными

Самая основная разница между TCP и UDP (User Datagram Protocol, протоколом дейтаграмм пользователя), который является его двоюродным братом на том же самом уровне, состоит в том, что он передаёт данные некоторым организованным и надёжным образом. Тот факт что все операции гарантируют доставку обычно характеризует TCP как протокол, ориентированный на соединение. Он осуществляет это первичным установлением троекратного квитирования (handshake) для синхронизации имеющейся нумерации последовательности между передающей и принимающей сторонами SYN, SYN-ACK и ACK.

Подтверждение (acknowledgement) применяется для отслеживания последовательных сегментов при их диалоге. Наконец, по окончанию данного диалога одна сторона отправит сообщение FIN, причём другая сторона ответит ACK на это сообщение FIN а также отправит некое сообщение FIN со своей стороны. Затем сторона инициатор выдаст ACK на полученный FIN.

Как и многие из тех, кто испытывал проблемы с неким соединением TCP, могут поведать вам, что данная операция может оказаться достаточно сложной. Конечно, можно догадаться, что в основном данная операция выполняется в фоновом режиме.

О данном протоколе TCP могут быть написаны целые книги; действительно, очень много исключительных книг было ему посвящено.

[Замечание]Замечание

Поскольку данный раздел является очень беглым обзором, если вы заинтересовались, The TCP/IP Guide является исключительным свободно доступным источником чтобы погрузить глубже в данный вопрос.

UDP

UDP также является ключевым участником имеющегося комплекта протокола Интернет. Как и TCP, он находится на 4 уровне модели OSI, который отвечает за доставку сегментов данных между прикладным уровнем и уровнем IP. В отличие от TCP его заголовок состоит всего лишь из 64 бит, который содержит только порт источника и получателя, длину и контрольную сумму. Такой легковесный заголовок делает его идеальным для приложений, предпочитающих более быструю доставку без установления определённого сеанса между двумя хостами или необходимости гарантированной доставки данных. Возможно это сложно представить в наши дни быстрых соединений интернет, однако такой дополнительный заголовок составлял значительную разницу в скорости передачи в ранние дни X.21 и соединений ретрансляции кадров (frame relay). Несмотря на важность сбережения скорости самой по себе, отсутствие установления различных состояний подобных TCP также сберегает вычислительные ресурсы на имеющихся двух оконечных точках.

 

Рисунок 6


Заголовок UDP (источник

Теперь вы можете задаться вопросом зачем вообще пользоваться UDP в наши дни; принимая во внимание отсутствие надёжной передачи, разве мы не желаем чтобы все наши соединения были надёжными и свободными от ошибок? Если вы задумаетесь о некотором мультимедийном приложении видео потока или вызове Skype {Прим. пер.: или сеансе удалённого рабочего места RDP Windows/ VMware/ XenServer/ FusionAccess/ VNC}, такие приложения получат преимущества от более лёгкого заголовка в случае, когда приложению всего лишь нужно доставить текужую дейтаграмму так быстро, как это только возможно. Вы также можете рассмотреть процесс просмотра DNS. Когда набранный вами в браузере адрес переводится в понятный компьютеру адрес, этот пользователь получает выгоду от более лёгкого процесса так как это случится даже "до" доставки самого первого бита информации вам с вашего любимого вебсайта.

Опять же, данный раздел не восстанавливает справедливость по теме UDP и читателю предлагается изучить данную тему в различных источниках если он/ она заинтересован в получении дополнительных знаний в отношении UDP.

IP

Как сказали бы сетевые инженеры, они сами ";живут" на уровне IP, который является 3 уровнем согласно модели OSI. IP имеет задание адресации и маршрутизации между оконечными узлами, помимо всего прочего. Именно адресация IP, вероятно, является наиболее важным заданием. Само адресное пространство подразделяется на две части; сетевую порцию и порцию хоста. Именно маска подсети указывает какая порция адреса относится к сетевой части, а какая к самому хосту. И IPv4, и, позднее, IPv6 отображают имеющийся адрес в нотации с точками, например, 192.168.0.1. Маска подсети может либо представляться в нотации с точками (255.255.255.0), либо с применением переднего слеша для отображения числа бит, которые должны рассматриваться как биты сети (/24).

 

Рисунок 7


Заголовок IPv4 (источник

Заголовок IPv6, последующее за IPv4 поколение заголовка IP, имеет некую фиксированную порцию и различные расширяющие заголовки.

 

Рисунок 8


Заголовок IPv6 (источник

Поле Next Header в разделе фиксированного заголовка может указывать некий последующий расширительный заголовок, который несёт дополнительную информацию. Такие расширительные заголовки могут содержать информацию о маршрутизации и фрагментации. Как бы сильно разработчики протокола не желали перейти с IPv4 на IPv6, интернет сегодня всё ещё достаточно много адресации выполняет при помощи IPv4.

NAT IP и безопасность

NAT (Network Address Translation, трансляция сетевого адреса) обычно используется для трансляции диапазона частных IPv4 адресов в общедоступные, допускающие маршрутизацию адреса IPv4. Но также это может означать и некую трансляцию между IPv4 в IPv6, например, в пограничных областях, когда IPv6 используется внутри самой сетевой среды, которые подлежат трансляции в IPv4 в том случае, когда эти пакета покидают данную сетевую среду. Порой NAT6to6 используется также по причинам безопасности.

Безопасность - это непрерывный процесс, который объединяет все аспекты сетевого взаимодействия, включая автоматизацию и Python. Данная книга имеет целью применение Python чтобы помочь вам в управлении сетевой средой; безопасности будет посвящена часть той главы которая применяет SSHv2 поверх telnet. Мы также рассмотрим, как мы можем применять Python и другие цепочки инструментов для получения визуализации сети.

Понятия маршрутизации IP

По моему личному мнению, маршрутизация IP состоит в том, чтобы иметь все необходимые промежуточные устройства между двумя оконечными пунктами обмена всеми пакетами между ними на основе имеющегося IP заголовка. Для каждого взаимодействия в интернете данный пакет будет перемещаться по различным промежуточным устройствам. Как уже упоминалось, такие промежуточные устройства состоят из маршрутизаторов, коммутаторов, оптического оборудования и различного прочего снаряжения, которые не рассматриваются за пределами сетевого и транспортного уровня. При аналогии с поездкой по дорогам вы можете отправиться в путешествие по Соединённым Штатам из города Сан Диего в Калифорнии в город Сиэтл в Вашингтоне. Адрес IP источника будет аналогом Сан Диего, а адресом IP назначения может быть указан Сеэтл. По своему пути вы можете останавливаться во множестве разнообразных промежуточных пунктах, таких Лос Анжелес, Сан Франциско и Портленд. Их все можно рассматривать как маршрутизаторы и коммутаторы между источником и пунктом назначения.

Почему это было важно? В некотором смысле данная книга посвящена управлению и оптимизации таких промежуточных устройств. В эпоху мега ЦОД, которые занимают размеры нескольких футбольных полей, необходимость эффективного, гибкого и экономически обоснованного подхода к управлению сетевой средой становится существенным моментом конкурентного преимущества для компаний. В последующих главах мы погрузимся в то, как мы можем применять программирование Python для эффективного управления своей сетевой средой.

Обзор языка Python

Если коротко, данная книга посвящена облегчению нашей жизни при помощи Python. Но что такое Python и почему именно он является избранным языком для многих инженеров DevOps? Словами фонда Python Executive Summary (https://www.python.org/doc/essays/blurb/):

Python является языком программирования с интерпретатором и объектно- ориентацией, а также обладающим высоким уровнем и при этом с динамической семантикой. Его встроенная структура данных высокого уровня в комбинации с динамической типизацией и динамическим связыванием делают его очень привлекательным для Быстрой разработки приложений, а также для применения в качестве языка сценариев или склеивающего языка для соединения имеющихся компонентов в одно целое. Python прост, обладает лёгким в освоении синтаксисе придающем особую значимость читабельности и, тем самым, снижает стоимость сопровождения.

Если вы в какой- то степени новичок в программировании, тогда слова объектно- ориентированная, динамическая семантика не означают для вас чего- то существенного. Однако я думаю, что все мы согласимся что Быстрая разработка приложений, простота и лёгкость обучения синтаксису звучат как хорошие понятия. Python как язык интерпретатора означает, что не требуется никакой процесс компиляции, поэтому значительно возрастает скорость процесса написания, проверки и изменения ваших программ. Для простых сценариев, в случае падения вашего сценария несколько операторов печати это обычно всё что вам нужно чтобы выяснить что идёт не так. Применение интерпретатора также означает, что Python просто переносится на различные типы операционных систем и программы Python, написанные в Windows могут применяться в Linux и Mac.

Объектно- ориентированная природа поощряет повторное применение кода посредством его разбиения на простые многоразовые формы такие как модули и пакеты. Фактически все файлы Python являются модулями, которые могут повторно применяться или импортироваться в другую программу Python. Это делает простым совместное использование программ между инженерами и поощряет повторное применение кода. У Python также имеются некий батарейки с мантрами, что означает, что нет нужды загружать дополнительный код для общих задач. Чтобы достичь этого и при том не раздувать черезчур сам код, при установке самого интерпретатора Python устанавливается некий набор стандартных библиотек. Для распространённых задач, таких как регулярные выражения, математические функции, а также декодирование JSON, всё что вам нужно, это оператор import и ваш интерпретатор перемести эти функции в вашу программу. Именно это я бы хотел рассмотреть как одно из убийственных свойств Python.

Наконец, тот факт, что код Python может стартовать с относительно небольшого сценария в несколько строк кода и превращаться в полноценную производственную систему, это очень удобно для сетевых инженеров. Как многие из нас знают, сама сетевая среда обычно органично развивается без некоего генерального плана. Язык, который может расти вместе с вашей сетью в размере неоценим. Вы можете быть удивлены, увидев язык, который многими считался языком сценариев и который при этом применялся для полноценных производственных систем (организации, применяющие Python, https://wiki.python.org/moin/OrganizationsUsingPython).

Если вы когда либо работали в среде, в которой вы должны переключаться по роду деятельности между платформами различных производителей, такими как Cisco IOS и Juniper Junos, вы знаете какая головная боль состоит в переключении между синтаксисом и применением когда вы пытаетесь достичь одной и той же цели. При помощи гибкости Python достаточной для больших и малых программ, больше нет такого переключения контекста, потому что это всего лишь Python.

На протяжении остатка данной главы мы предпримем тур по верхам нашего языка Python чтобы слегка освежить навыки. Если вы уже знакомы с основами, чувствуйте себя в праве перескочить к следующей главе.

Версии Python

на момент написания данной книги в начале 2017, Python Python пребывает в процессе перехода с Python версии 2 на Python версии 3. К сожалению Python 3 не совместим в обратную сторону с Python 2. Когда я произношу переход, имейте в виду, что Python 3 был выпущен в далёком 2008, более 9 лет назад с активной разработкой и наиболее поздней версией 3.6. Самый последний выпуск Python 2.x, 2.7 был выпущен шесть лет тому назад, в 2010. К счастью, на одной и той же машине могут сосуществовать обе версии. Что касается лично меня, я применяю Python 2 в качестве своего интерпретатора по умолчанию, когда я набираю Python в приглашении командной строки и я использую Python 3 когда мне необходимо применять Python 3. Дополнительная информация приводится в нашем следующем разделе об исполнении интерпретатора Python, однако вот пример исполнения Python 2 и Python 3 на машине Ubuntu Linux:


echou@pythonicNeteng:~$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> exit()
echou@pythonicNeteng:~$ python3

Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for
more information.
>>> exit()
 	   

С завершающим расширенную поддержку выпуском 2.7, оставляющим только обновления безопасности, большинство инфраструктур Python теперь поддерживают Python 3. Python3 также имеет множество полезных свойств, например, асинхронный ввод/ вывод, который может получать преимущества при нашей потребности в оптимизации кода. Данная книга будет применять Python 3 для своих примеров кода.

Если некоторые особые библиотеки не поддерживают Python 3, например, Ansible (они активно работают над переносом на Python 3), это будет указываться с тем чтобы вы могли вместо него применять Python 2.

Операционная система

Как уже упоминалось, Python является кросс платформенным. Программы Python могут исполняться в Windows, Mac, и Linux. {Прим. пер.: а также FreeBSD и массе прочих ОС} На практике необходимо придерживаться некоторых предосторожностей когда вам необходимо гарантировать кроссплатформенную совместимость, например, принять меры предосторожности о хитростях с обратными слешами в именах файлов Windows {Прим. пер.: подробнее см. Исправление имён файлов Unix/Linux/POSIX}. Поскольку данная книга предназначена для DevOps, системных и сетевых инженеров, Linux является предпочитаемой платформой для целевой аудитории, особенно для промышленных применений. Весь код данной книги был проверен на машине с Linux Ubuntu 16.06 LTS. Я также приложил все свои усилия чтобы убедиться, что данный код работает также на платформе Windows и Mac.

Если вас интересуют подробности применяемой ОС, они таковы:


echou@pythonicNeteng:~$ uname -a
Linux pythonicNeteng 4.4.0-31-generic #50-Ubuntu SMP
Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64
GNU/Linux
echou@pythonicNeteng:~$
 	   

Исполнение программ Python

Программы Python исполняются неким интерпретатором, что означает, что данный код подаётся через такой интерпретатор для его исполнения лежащей в основе операционной системой и отображения результатов. Существует ряд различных реализаций данного интерпретатора в имеющемся сообществе разработчиков Python, такие как IronPython и Jython. В данной книге мы будем иметь дело с наиболее распространённой на сегодняшний день версией интерпретатора Python, СPython.

Одним из способов, которым вы можете применять Python состоит в получении преимуществ от имеющегося интерактивного приглашения. Это полезно когда вы желаете быстро проверить некую порцию кода или концепцию Python без написания программы целиком. Это обычно выполняется простым набором с клавиатуры Python:


Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for
more information.
>>> print("hello world")
hello world
>>>
 	   
[Замечание]Замечание

Отметим скобки в операторе печати. В Python 3 оператор печати является функцией; следовательно ему необходимы скобки. В Python 2 вы можете опускать все скобки. {Прим. пер.: но рекомендуем привыкать к ним везде.} .

Такой интерактивный режим является одним из самых полезных свойств Python. В такой интерактивной оболочке вы можете набирать любой разрешённый оператор или последовательность операторов и немедленно получать результат обратно. Обычно я использую это для исследования некоторого свойства или библиотеки, с которыми я не знаком. А вы говорите моментальное удовольствие!

[Замечание]Замечание

Если вы не получаете обратно приглашения оболочки Python в Windows, у вас может отсутствовать данная программа в пути поиска path. Самые последние версии программы установщика Python Windows предоставляют флаговый блок для добавления Python в ваш системный путь поиска; проверьте что он был отмечен. Либо вы можете добавить данную программу в свой путь поиска вручную, перейдя в Environment Settings.

Наиболее распространённым способом исполнения программ, однако, является их сохранение в вашем файле Python и последующем исполнении их в интерпретаторе. Это убережёт вас от набора одних и тех же операторов снова и снова, так как вы это делаете в интерактивной оболочке. Файлы Python являются всего лишь обычными текстовыми файлами, которые обычно сохраняются с расширением .py. В мире *nix вы также можете добавить поверх строку shebang #!) для определения того интерпретатора, который вы используете для выполнения данного файла. Символ # может применяться для определения комментариев, которые не будут исполняться вашим интерпретатором. Приводимый ниже файл helloworld.py имеет такие операторы:


# This is a comment
print("hello world")
 	   

Он может быть исполнен следующим образом:


echou@pythonicNeteng:~/Master_Python_Networking/
Chapter1$ python helloworld.py
hello world
echou@pythonicNeteng:~/Master_Python_Networking/
Chapter1$
 	   

Встроенные типы Python

Python имеет некоторые стандартные типы, встроенные в сам интерпретатор:

  • None: Это объект Null

  • Численный: int, long, float, complex и bool (это подкласс int со значениями True или False)

  • Последовательности: str (строка), list (список), tuple (кортеж) и range (диапазон)

  • Соответствие: dict

  • Множества: set и frozenset

Тип None

Тип None обозначает некий объект без значения. именно это возвращается функцией, которая в явном виде ничего не возвращает. Тип None также применяется в качестве аргумента функции для определения ошибки в случае, когда вызывающий её не передал некоторого реального значения.

Числа

Численные объекты Python в основном являются собственно числами. За исключением Булева, все числовые типы int, long, float и complex имеют знак, что означает, что они могут быть положительными и отрицательными. Булевский тип (логический) является подклассом значений целого, который может иметь только два значения: 1 для True и 0 для False. Остальные числовые типы различаются только тем насколько точно они могут представлять данное число; например, int это целые числа с ограниченным диапазоном, а long - с неограниченным. float - это числа, применяющие представление с двойной точностью (64- бита) на данной машине. {Прим. пер.: представление может различаться для разных процессоров, что может стать источником очень трудно обнаруживаемых ошибок при переносе кодов с платформы на платформу. Помните об этом!}

Последовательности

Последовательности являются упорядоченными наборами объектов с неким индексом из неотрицательных целых. В этом и нескольких последующих разделах мы будем применять свой интерактивный интерпретатор для иллюстрации различных типов. Не стесняйтесь набирать то же самое на своём собственном компьютере.

Порой это может оказаться сюрпризом для людей, что string на самом деле некий тип последовательности. Однако если вы взглянете пристальней, строки это последовательности помещённых вместе символов. Строки заключаются в одиночные, двойные или тройные кавычки. В последующем примере отметим ту строку, которая слишком длинна и тройные кавычки позволяют нам расширить такую строку на несколько строчек:


>>> a = "networking is fun"
>>> b = 'DevOps is fun too'
>>> c = """what about coding?
... super fun!"""
>>>
 	   

Другими двумя широко применяемыми типами последовательностей являются списки и кортежи. Списки являются последовательностями произвольных объектов. Списки можно создавать при помощи заключения своих объектов в квадратные скобки. В точности как и строки, списки индексируются неотрицательными целыми, начинающимися с нуля. Значения списков выбираются путём ссылки по значению индекса:


>>> vendors = ["Cisco", "Arista", "Juniper"]
>>> vendors[0]
'Cisco'
>>> vendors[1]
'Arista'
>>> vendors[2]
'Juniper'
 	   

Кортежи похожи на списки и создаются заключением всех значений в круглые скобки. Как и списки, значения в данном кортеже выбираются путём ссылки на его индексный номер. В отличии от списков, все значения не могут изменяться после их создания:


>>> datacenters = ("SJC1", "LAX1", "SFO1")
>>> datacenters[0]
'SJC1'
>>> datacenters[1]
'LAX1'
>>> datacenters[2]
'SFO1'
 	   

Некоторые операции являются общими для всех типов последовательностей, например, возвращение некоторого элемента по значению его индекса, а также расслоение:


>>> a
'networking is fun'
>>> a[1]
'e'
>>> vendors
['Cisco', 'Arista', 'Juniper']
>>> vendors[1]
'Arista'
>>> datacenters
('SJC1', 'LAX1', 'SFO1')
>>> datacenters[1]
'LAX1'
>>>
>>> a[0:2]
'ne'
>>> vendors[0:2]
['Cisco', 'Arista']
>>> datacenters[0:2]
('SJC1', 'LAX1')
>>>
 	   
[Замечание]Замечание

Отметим, что индекс начинается с 0. Таким образом, 1 на самом деле второй элемент в имеющейся последовательности.

Имеются также общие функции, которые могут применяться к типам последовательностей, такие как проверка общего числа элементов, а также минимальное и максимальное значения:


>>> len(a)
17
>>> len(vendors)
3
>>> len(datacenters)
3
>>>
>>> b = [1, 2, 3, 4, 5]
>>> min(b)
1
>>> max(b)
5
 	   

Неудивительно, что существуют различные методы, которые применяются только к строкам. Стоит отметить, что эти методы не изменяют имеющиеся строковые данные и всегда возвращают новую строку. Если вы хотите использовать новое значение для строки, вам необходимо перехватить возвращаемое значение и присвоить его другой переменной:


>>> a
'networking is fun'
>>> a.capitalize()
'Networking is fun'
>>> a.upper()
'NETWORKING IS FUN'
>>> a
'networking is fun'
>>> b = a.upper()
>>> b
'NETWORKING IS FUN'
>>> a.split()
['networking', 'is', 'fun']
>>> a
'networking is fun'
>>> b = a.split()
>>> b
['networking', 'is', 'fun']
>>>
 	   

Вот некоторые общеупотребимые методы для какого- то списка. Такой список является очень полезной структурой с точки зрения ввода нескольких элементов и выполнения итераций с их помощью. Например, мы можем создать некий список коммутаторов ствола ЦОД и применить один и тот же список доступа к ним всем итеративно пройдясь по ним, последовательно один за другим. Так как некий список значений может изменяться после создания (в отличии от кортежей), мы также можем расширять и выделять имеющийся список по мере продвижения в данной программе.


>>> routers = ['r1', 'r2', 'r3', 'r4', 'r5']
>>> routers.append('r6')
>>> routers
['r1', 'r2', 'r3', 'r4', 'r5', 'r6']
>>> routers.insert(2, 'r100')
>>> routers
['r1', 'r2', 'r100', 'r3', 'r4', 'r5', 'r6']
>>> routers.pop(1)
'r2'
>>> routers
['r1', 'r100', 'r3', 'r4', 'r5', 'r6']
 	   

Соответствия

Python предоставляет один тип соответствия, называемый словарём. Я себе представляю словарь как базу данных для бедных, так как он содержит объекты, которые могут индексироваться ключами. Его часто называют ассоциативным массивом или таблицей хэшей в прочих языках программирования. Если вы уже применяли какие- либо подобные словарям объекты в других языках, вы будете знать, что это мощный тип, так как вы можете ссылаться на свой объект посредством читабельного ключа. Этот ключ более интуитивно понятен для тех несчастных людей, которые пытаются сопровождать ваш код, вероятно, через несколько месяцев после того как вы написали этот код в 2 часа утром. Данный объект также может быть другим типом данных, таким как список. Вы можете создать некий словарь с помощью фигурных скобок:


>>> datacenter1 = {'spines': ['r1', 'r2', 'r3', 'r4']}
>>> datacenter1['leafs'] = ['l1', 'l2', 'l3', 'l4']
>>> datacenter1
{'leafs': ['l1', 'l2', 'l3', 'l4'], 'spines': ['r1',
'r2', 'r3', 'r4']}
>>> datacenter1['spines']
['r1', 'r2', 'r3', 'r4']
>>> datacenter1['leafs']
['l1', 'l2', 'l3', 'l4']
 	   
[Замечание]Замечание

{Прим. пер.: отметим, что элементы в словаре, в отличие от последовательностей, не упорядочены по определению. То есть в предыдущем примере априори нельзя сказать что листья идут после стволов.}

Множества

Множество применяется для того чтобы содержать неупорядоченные коллекции объектов. В оличии от списков и кортежей наборы не имеют порядка и не могут индекисроваться числами. Однако имеется одно свойство, которое делает множества выделяющимися и полезными: все элементы в некотором наборе никогда не дублируются. Представим себе, что у вас имеется некий список IP, который вам необходимо поместить в некий список доступа. Единственная проблема в данном списке IP состоит в том, что он полон дублирований. Теперь подумайте о том как вы можете применить цикл для сортировки с целью выявления уникальных элементов, в то время как имеющийся встроенный тип множества позволил бы вам избежать все повторяющиеся элементы всего лишь одной строкой кода. Если быть честным, я не применяю множества очень часто, однако когда мне это требуется, я всегда очень благодарен их наличию. Когда создаётся множество множеств, их можно сравнивать друг с другом при помощи объединения, пересечения и различия:


>>> a = "hello"
>>> set(a)
{'h', 'l', 'o', 'e'}
>>> b = set([1, 1, 2, 2, 3, 3, 4, 4])
>>> b
{1, 2, 3, 4}
>>> b.add(5)
>>> b
{1, 2, 3, 4, 5}
>>> b.update(['a', 'a', 'b', 'b'])
>>> b
{1, 2, 3, 4, 5, 'b', 'a'}
>>> a = set([1, 2, 3, 4, 5])
>>> b = set([4, 5, 6, 7, 8])
>>> a.intersection(b)
{4, 5}
>>> a.union(b)
{1, 2, 3, 4, 5, 6, 7, 8}
>>> 1 *
{1, 2, 3}
>>>
 	   

Операторы Python

Python имеет некоторые численные операторы, которые вы ожидаете получить; отметим, что усекающее деление (//, также называемое floor division - нижним делением) усекает получаемый результат до некоторого целого и десятичной точки и возвращает целое значение. {Прим. пер.: всегда вниз, 7//3=2 и -7//2=-3} Оператор взятия по модулю % возвращает остаток от деления:


>>> 1 + 2
3
>>> 2 - 1
1
>>> 1 * 5
5
>>> 5 / 1
5.0
>>> 5 // 2
2
>>> 5 % 2
1
 	   

Также имеются операции сравнения:


>>> a = 1
>>> b = 2
>>> a == b
False
>>> a > b
False
>>> a < b
True
>>> a <= b
True
 	   

Вы также можете обнаружить два оператора общего участия чтобы проверять содержится ли некий объект в каком- то типе последовательности:


>>> a = 'hello world'
>>> 'h' in a
True
>>> 'z' in a
False
>>> 'h' not in a
False
>>> 'z' not in a
True
 	   

Инструменты управления потоком Python

Операторы if, else и elif управляют условным исполнением кода. Как и следовало ожидать, имеющийся формат условного оператора таков:


if expression:
  do something
elif expression:
  do something if the expression meets
elif expression:
  do something if the expression meets
...
else:
  statement
 	   
[Замечание]Замечание

{Прим. пер.: обратим ваше внимание на роль отступа для обозначения вложенности (блочности) кода. Здесь нет в явном виде оператора конца блока. Эту роль исполняет отступ при написании кода. К этой особенности Python необходимо привыкнуть.}

Вот простой пример:


>>> a = 10
>>> if a > 1:
...   print("a is larger than 1")
... elif a < 1:
...   print("a is smaller than 1")
... else:
...   print("a is equal to 1")
...
a is larger than 1
>>>
 	   

Цикл while будет исполняться пока данное условие не станет ложным, поэтому будьте аккуратны с ним если вы не желаете выполнять это без конца:


while expression:
  do something
 	   

>>> a = 10
>>> b = 1
>>> while b < a:
... print(b)
... b += 1
...
123456789
 	   

Цикл for работает с любыми объектами, которые поддерживают итерацию; это означает, что все встроенные типы последовательностей, такие как списки, кортежи и строки могут применяться в некотором цикле for. Символ i в приводимом ниже цикле for является итеративной переменной, поэтому вы обычно можете указывать что- то, что является существенным в контексте вашего кода:


for i in sequence:
  do something
 	   

>>> a = [100, 200, 300, 400]
>>> for number in a:
... print(number)
...
100
200
300
400
 	   

Вы также можете создать свой собственный объект, который поддерживает протокол итерации и получить возможность применять оператор for для цикла по такому объекту:

[Замечание]Замечание

Построение таких объектов выходит за рамки данной главы, однако это полезное знание, которым стоит овладеть, вы можете прочесть дополнительно об этом: https://docs.python.org/3/c-api/iter.html.

Функции Python

Большую чать тех раз, когда вы обнаруживаете необходимость повторного применения кода, вам следует разбить код на содержащие себя порции в виде функций. Такая практика делает возможной лучшую модульность, её проще сопровождать, а также далает возможным повторное применение кода. Функции Python определяются при помощи ключевого слова def с идущим вслед за ним именем данной функции и последующими параметрами этой функции. Само тело функции состоит из подлежащих исполнению операторов Python. По окончанию функции вы можете выбрать возврат некоторого значения вызывавшему эту функцию {через ключевое слово return} или, по умолчанию, будет возвращён объект None если вы не определите какое- либо возвращаемое значение:


def name(parameter1, parameter2):
  statements
  return value
 	   

Мы обнаружим множество примеров функций в последующих главах, поэтому здесь представим только короткий пример:


>>> def subtract(a, b):
... c = a - b
... return c
...
>>> result = subtract(10, 5)
>>> result
5
>>>
 	   

Классы Python

Python является языком OOP (Object-Oriented Programming, объектно ориентированного программирования). Единственный способ, которым Python создаёт объекты, это ключевое слово class. Объект Python наиболее часто является неким набором функций (методов), переменных и атрибутов (свойств). Когда код определён, вы можете создавать экземпляры такого класса. Данный класс служит как бы копиркой всех последующих экземпляров.

Сам предмет объектного программирования выходит за рамки данной главы, поэтому мы приведём некий пример определения объекта маршрутизатора:


>>> class router(object):
... def __init__(self, name, interface_number,
vendor):
... self.name = name
... self.interface_number = interface_number
... self.vendor = vendor
...
>>>
 	   

Когда он определён, вы имеете возможность создать столько экземпляров данного класса, сколько пожелаете:


>>> r1 = router("SFO1-R1", 64, "Cisco")
>>> r1.name
'SFO1-R1'
>>> r1.interface_number
64
>>> r1.vendor
'Cisco'
>>>
>>> r2 = router("LAX-R2", 32, "Juniper")
>>> r2.name
'LAX-R2'
>>> r2.interface_number
32
>>> r2.vendor
'Juniper'
>>>
 	   

Безусловно, объекты Python и OOP намного шире. Мы увидим больше примеров в последующих главах.

Модули и пакеты Python

Любой файл исходного кода Python может использоваться в качестве модуля и все определяемые в этом файле исходного кода функции и классы могут применяться повторно. Для загрузки этого кода все ссылки на файлы таких модулей должны применять ключевое слово import. При импорте данного файла происходит следующее:

  1. Данный файл создаёт некое новое пространство имён для тех объектов, которые определены в данном файле.

  2. Вызвавшая сторона исполняет все те коды, которые содержатся в этом модуле.

  3. Данный файл создаёт некое имя внутри вызвавшей ого стороны, которое ссылается на подлежащий импорту модуль. Данное имя соответствует самому имени этого модуля.

Помните ту функцию subtract(), которую мы определили при помощи своей интерактивной оболочки? Для повторного использования данной функции мы можем поместить её в файл с названием subtract.py:


def subtract(a, b):
  c = a - b
  return c
 	   

В некотором файле в том же самом каталоге, что и subtract.py, вы можете запустить свой интерпретатор Python и импортировать данную функцию:


Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> import subtract
>>> result = subtract.subtract(10, 5)
>>> result
5
 	   

Это работает потому что по умолчанию Python вначале просматривает текущий каталог на предмет доступности модулей. Если находитесь в другом каталоге, вы можете вручную добавить некое местоположение поиска с помощью своего модуля sys посредством sys.path. Помните ту стандартную библиотеку, которую мы упоминали какое- то время тому назад? Вы догадались что это именно она использует файлы Python в качестве модулей.

Пакеты делают возможным собирать модули вместе в группы. Это дополнительно организует модули Python в некое более защищённое пространство имён для последующего совместного использования. Некий пакет определяется посредством создания некоторого каталога с именем, которое вы желаете применять в качестве такого пространства имён, затем вы можете поместить требуемый файл исходного кода модуля в данном каталоге. Чтобы Python понимал его в качестве некоторого пакета Python, просто создайте в этом каталоге некий файл __init__.py. В том же самом примере, что и файл subtract.py, если вы создадите некий каталог с названием math_stuff и создадите какой- то файл __init__.py:


echou@pythonicNeteng:~/Master_Python_Networking/Chapter1$ mkdir math_stuff
echou@pythonicNeteng:~/Master_Python_Networking/Chapter1$ touch math_stuff/__init__.py
echou@pythonicNeteng:~/Master_Python_Networking/Chapter1$ tree .
.
│   ​ helloworld.py
└───​ math_stuff
    ​ __init__.py
    ​ subtract.py

1 directory, 3 files
echou@pythonicNeteng:~/Master_Python_Networking/
Chapter1$
 	   

Тот способ, при помощи которого вы можете теперь ссылаться на этот модуль потребует теперь включение самого имени пакета:


>>> from math_stuff.subtract import subtract
>>> result = subtract(10, 5)
>>> result
5
>>>
 	   

Как вы можете видеть, модули и пакеты являются великолепным способом организации файлов большого кода и создания намного более простого способа совместного использования Python.

Выводы

В данной главе мы охватили модель OSI и рассмотрели такие комплекты протоколов как TCP, UDP и IP. Затем мы бегло ознакомились с языком Python, включая встроенные типы, операторы, управление потоками, функциями, классами, модулями и пакетами.

В своей следующей главе мы начнём просматривать применение Python для программирования взаимодействия с имеющимся сетевым оборудованием.