Документация Python неофициальный перевод

ipaddress.md

286 строк · 17.8 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3/howto/ipaddress.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Введение в модуль ipaddress89**автор:**1011Peter Moody1213**автор:**1415Nick Coghlan1617Обзор1819Этот документ представляет собой мягкое введение в модуль [`ipaddress`](https://python-all.ru/3/library/ipaddress.html#module-ipaddress). Он предназначен в первую очередь для пользователей, которые ещё не знакомы с терминологией IP-сетей, но может также быть полезен сетевым инженерам, желающим получить обзор того, как `ipaddress` представляет концепции IP-адресации.2021## Создание объектов адресов/сетей/интерфейсов2223Поскольку [`ipaddress`](https://python-all.ru/3/library/ipaddress.html#module-ipaddress) – это модуль для проверки и управления IP-адресами, первое, что нужно сделать – создать несколько объектов. Можно использовать `ipaddress` для создания объектов из строк и целых чисел.2425### Замечание о версиях IP2627Для читателей, не особенно знакомых с IP-адресацией, важно знать, что в настоящее время происходит переход с версии 4 протокола Internet Protocol (IP) на версию 6. Этот переход происходит в значительной степени потому, что версия 4 протокола не предоставляет достаточного количества адресов для удовлетворения потребностей всего мира, особенно с учётом растущего числа устройств, имеющих прямое подключение к интернету.2829Объяснение деталей различий между двумя версиями протокола выходит за рамки данного введения, но читатели должны, по крайней мере, знать, что эти две версии существуют, и иногда может потребоваться принудительно использовать одну или другую версию.3031### IP-адреса хостов3233Адреса, часто называемые «адресами хостов», являются самой базовой единицей при работе с IP-адресацией. Самый простой способ создать адреса – использовать фабричную функцию [`ipaddress.ip_address()`](https://python-all.ru/3/library/ipaddress.html#ipaddress.ip_address), которая автоматически определяет, создавать ли IPv4 или IPv6 адрес на основе переданного значения:3435```python36>>> ipaddress.ip_address('192.0.2.1')37IPv4Address('192.0.2.1')38>>> ipaddress.ip_address('2001:DB8::1')39IPv6Address('2001:db8::1')40```4142Адреса также можно создавать непосредственно из целых чисел. Значения, помещающиеся в 32 бита, считаются IPv4-адресами:4344```python45>>> ipaddress.ip_address(3221225985)46IPv4Address('192.0.2.1')47>>> ipaddress.ip_address(42540766411282592856903984951653826561)48IPv6Address('2001:db8::1')49```5051Чтобы принудительно использовать IPv4 или IPv6 адреса, соответствующие классы можно вызвать напрямую. Это особенно полезно для принудительного создания IPv6 адресов из небольших целых чисел:5253```python54>>> ipaddress.ip_address(1)55IPv4Address('0.0.0.1')56>>> ipaddress.IPv4Address(1)57IPv4Address('0.0.0.1')58>>> ipaddress.IPv6Address(1)59IPv6Address('::1')60```6162### Определение сетей6364Адреса хостов обычно группируются в IP-сети, поэтому [`ipaddress`](https://python-all.ru/3/library/ipaddress.html#module-ipaddress) предоставляет способ создания, проверки и управления определениями сетей. Объекты IP-сетей создаются из строк, определяющих диапазон адресов хостов, входящих в эту сеть. Простейшая форма такой информации – пара «адрес сети/префикс сети», где префикс определяет количество старших битов, которые сравниваются для определения, является ли адрес частью сети, а адрес сети задаёт ожидаемое значение этих битов.6566Как и для адресов, предусмотрена фабричная функция, которая автоматически определяет правильную версию IP:6768```python69>>> ipaddress.ip_network('192.0.2.0/24')70IPv4Network('192.0.2.0/24')71>>> ipaddress.ip_network('2001:db8::0/96')72IPv6Network('2001:db8::/96')73```7475Объекты сетей не могут иметь установленных битов хоста. Практический эффект этого заключается в том, что `192.0.2.1/24` не описывает сеть. Такие определения называются объектами интерфейсов, поскольку нотация «ip-на-сети» обычно используется для описания сетевых интерфейсов компьютера в заданной сети; они описываются далее в следующем разделе.7677По умолчанию попытка создать объект сети с установленными битами хоста приведёт к возникновению исключения [`ValueError`](https://python-all.ru/3/library/exceptions.html#ValueError). Чтобы запросить принудительное обнуление дополнительных битов, в конструктор можно передать флаг `strict=False`:7879```python80>>> ipaddress.ip_network('192.0.2.1/24')81Traceback (most recent call last):82   ...83ValueError: 192.0.2.1/24 has host bits set84>>> ipaddress.ip_network('192.0.2.1/24', strict=False)85IPv4Network('192.0.2.0/24')86```8788Хотя строковая форма предоставляет значительно большую гибкость, сети также можно определять с помощью целых чисел, как и адреса хостов. В этом случае сеть считается содержащей только единственный адрес, заданный целым числом, поэтому префикс сети включает весь сетевой адрес:8990```python91>>> ipaddress.ip_network(3221225984)92IPv4Network('192.0.2.0/32')93>>> ipaddress.ip_network(42540766411282592856903984951653826560)94IPv6Network('2001:db8::/128')95```9697Как и в случае с адресами, создание сети определённого типа можно принудительно выполнить, вызвав конструктор класса напрямую, а не используя фабричную функцию.9899### Интерфейсы хостов100101Как уже упоминалось, если нужно описать адрес в конкретной сети, ни классы адресов, ни классы сетей не подходят. Обозначение вроде `192.0.2.1/24` обычно используется сетевыми инженерами и разработчиками инструментов для межсетевых экранов и маршрутизаторов как сокращение для «хост `192.0.2.1` в сети `192.0.2.0/24`». Соответственно, [`ipaddress`](https://python-all.ru/3/library/ipaddress.html#module-ipaddress) предоставляет набор гибридных классов, которые связывают адрес с конкретной сетью. Интерфейс для создания таких объектов совпадает с интерфейсом для определения сетевых объектов, за исключением того, что часть адреса не обязана быть сетевым адресом.102103```python104>>> ipaddress.ip_interface('192.0.2.1/24')105IPv4Interface('192.0.2.1/24')106>>> ipaddress.ip_interface('2001:db8::1/96')107IPv6Interface('2001:db8::1/96')108```109110Целочисленные входные данные принимаются (как и для сетей), а использование определённой версии IP можно принудительно задать, напрямую вызвав соответствующий конструктор.111112## Просмотр объектов Address/Network/Interface113114Раз уж вы создали объект IPv(4|6)(Address|Network|Interface), скорее всего, вы захотите получить о нём информацию. [`ipaddress`](https://python-all.ru/3/library/ipaddress.html#module-ipaddress) старается сделать это простым и интуитивно понятным.115116Извлечение версии IP:117118```python119>>> addr4 = ipaddress.ip_address('192.0.2.1')120>>> addr6 = ipaddress.ip_address('2001:db8::1')121>>> addr6.version1226123>>> addr4.version1244125```126127Получение сети из интерфейса:128129```python130>>> host4 = ipaddress.ip_interface('192.0.2.1/24')131>>> host4.network132IPv4Network('192.0.2.0/24')133>>> host6 = ipaddress.ip_interface('2001:db8::1/96')134>>> host6.network135IPv6Network('2001:db8::/96')136```137138Определение количества отдельных адресов в сети:139140```python141>>> net4 = ipaddress.ip_network('192.0.2.0/24')142>>> net4.num_addresses143256144>>> net6 = ipaddress.ip_network('2001:db8::0/96')145>>> net6.num_addresses1464294967296147```148149Перебор «используемых» адресов в сети:150151```python152>>> net4 = ipaddress.ip_network('192.0.2.0/24')153>>> for x in net4.hosts():154...     print(x)155192.0.2.1156192.0.2.2157192.0.2.3158192.0.2.4159...160192.0.2.252161192.0.2.253162192.0.2.254163```164165Получение маски сети (т.е. битов, установленных в соответствии с префиксом сети) или маски хоста (все биты, не входящие в маску сети):166167```python168>>> net4 = ipaddress.ip_network('192.0.2.0/24')169>>> net4.netmask170IPv4Address('255.255.255.0')171>>> net4.hostmask172IPv4Address('0.0.0.255')173>>> net6 = ipaddress.ip_network('2001:db8::0/96')174>>> net6.netmask175IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')176>>> net6.hostmask177IPv6Address('::ffff:ffff')178```179180Развёртывание или сжатие адреса:181182```python183>>> addr6.exploded184'2001:0db8:0000:0000:0000:0000:0000:0001'185>>> addr6.compressed186'2001:db8::1'187>>> net6.exploded188'2001:0db8:0000:0000:0000:0000:0000:0000/96'189>>> net6.compressed190'2001:db8::/96'191```192193Хотя IPv4 не поддерживает развёртывание или сжатие, соответствующие объекты всё равно предоставляют соответствующие свойства, чтобы код, не зависящий от версии, мог легко обеспечить использование самой краткой или самой полной формы для IPv6-адресов, при этом корректно обрабатывая IPv4-адреса.194195## Сети как списки адресов196197Иногда бывает полезно рассматривать сети как списки. Это означает, что их можно индексировать, например, так:198199```python200>>> net4[1]201IPv4Address('192.0.2.1')202>>> net4[-1]203IPv4Address('192.0.2.255')204>>> net6[1]205IPv6Address('2001:db8::1')206>>> net6[-1]207IPv6Address('2001:db8::ffff:ffff')208```209210Это также означает, что сетевые объекты можно использовать с синтаксисом проверки принадлежности к списку, например, так:211212```python213if address in network:214    # выполнить действие215```216217Проверка принадлежности выполняется эффективно на основе префикса сети:218219```python220>>> addr4 = ipaddress.ip_address('192.0.2.1')221>>> addr4 in ipaddress.ip_network('192.0.2.0/24')222True223>>> addr4 in ipaddress.ip_network('192.0.3.0/24')224False225```226227## Сравнения228229[`ipaddress`](https://python-all.ru/3/library/ipaddress.html#module-ipaddress) предоставляет несколько простых и, как надеется, интуитивно понятных способов сравнения объектов, где это имеет смысл:230231```python232>>> ipaddress.ip_address('192.0.2.1') < ipaddress.ip_address('192.0.2.2')233True234```235236Исключение [`TypeError`](https://python-all.ru/3/library/exceptions.html#TypeError) возникает при попытке сравнить объекты разных версий или разных типов.237238## Использование IP-адресов с другими модулями239240Другие модули, работающие с IP-адресами (например, [`socket`](https://python-all.ru/3/library/socket.html#module-socket)), обычно не принимают объекты этого модуля напрямую. Вместо этого их необходимо преобразовать в целое число или строку, которые приемлемы для другого модуля:241242```python243>>> addr4 = ipaddress.ip_address('192.0.2.1')244>>> str(addr4)245'192.0.2.1'246>>> int(addr4)2473221225985248```249250## Получение более подробной информации при сбое создания экземпляра251252При создании объектов адреса/сети/интерфейса с помощью версионно-независимых фабричных функций любые ошибки будут сообщаться как [`ValueError`](https://python-all.ru/3/library/exceptions.html#ValueError) с общим сообщением об ошибке, в котором просто говорится, что переданное значение не распознано как объект этого типа. Отсутствие конкретной ошибки связано с тем, что для предоставления более подробной информации о причине отклонения необходимо знать, должно ли значение *считаться* IPv4 или IPv6.253254Для поддержки сценариев, в которых полезно иметь доступ к этим дополнительным сведениям, отдельные конструкторы классов фактически вызывают подклассы [`ValueError`](https://python-all.ru/3/library/exceptions.html#ValueError): [`ipaddress.AddressValueError`](https://python-all.ru/3/library/ipaddress.html#ipaddress.AddressValueError) и [`ipaddress.NetmaskValueError`](https://python-all.ru/3/library/ipaddress.html#ipaddress.NetmaskValueError), чтобы указать, какая именно часть определения не была разобрана корректно.255256Сообщения об ошибках становятся значительно более подробными при прямом использовании конструкторов классов. Например:257258```python259>>> ipaddress.ip_address("192.168.0.256")260Traceback (most recent call last):261  ...262ValueError: '192.168.0.256' does not appear to be an IPv4 or IPv6 address263>>> ipaddress.IPv4Address("192.168.0.256")264Traceback (most recent call last):265  ...266ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.0.256'267268>>> ipaddress.ip_network("192.168.0.1/64")269Traceback (most recent call last):270  ...271ValueError: '192.168.0.1/64' does not appear to be an IPv4 or IPv6 network272>>> ipaddress.IPv4Network("192.168.0.1/64")273Traceback (most recent call last):274  ...275ipaddress.NetmaskValueError: '64' is not a valid netmask276```277278Однако оба специфичных для модуля исключения имеют [`ValueError`](https://python-all.ru/3/library/exceptions.html#ValueError) в качестве родительского класса, поэтому если вас не интересует конкретный тип ошибки, вы по-прежнему можете писать код, подобный следующему:279280```python281try:282    network = ipaddress.IPv4Network(address)283except ValueError:284    print('address/netmask is invalid for IPv4:', address)285```286