Это будет работать не всегда (возвращает 127.0.0.1 на машинах, имеющих имя хоста в /etc/hosts виде 127.0.0.1), альтернативным вариантом было бы то, что показывает gimel, используйте socket.getfqdn() вместо этого. Конечно, вашему компьютеру нужно разрешаемое имя хоста.
Ответ 3
Этот метод возвращает "основной" IP-адрес в локальном окне (тот, у которого маршрут по умолчанию).
НЕ требует маршрутизируемого сетевого доступа или какого-либо подключения вообще.
Работает, даже если все интерфейсы отключены от сети.
Не требует и даже не пытается получить где-либо еще.
Работает с NAT, общедоступными, частными, внешними и внутренними IP-адресами
Чистый Python 2 (или 3) без внешних зависимостей.
Работает в Linux, Windows и OSX.
Python 3 или 2:
import socket defget_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(0) try: # doesn't even have to be reachable s.connect(('10.254.254.254', 1)) IP = s.getsockname()[0] except Exception: IP = '127.0.0.1' finally: s.close() return IP print(get_ip())
Это возвращает единственный IP-адрес, который является основным (с маршрутом по умолчанию). Если вместо этого вам нужны все IP-адреса, подключенные ко всем интерфейсам (включая localhost и т.д.), посмотрите что-то вроде этого ответа.
Если вы находитесь за брандмауэром NAT, например, за вашим домашним маршрутизатором Wi-Fi, то это не покажет ваш общедоступный IP-адрес NAT, а вместо этого ваш частный IP-адрес в локальной сети, который имеет маршрут по умолчанию к вашему локальному маршрутизатору Wi-Fi. Если вместо этого вам нужен ваш внешний IP-адрес:
запуск этой функции на ЭТОМ внешнем устройстве (wifi-маршрутизаторе) или
подключение к внешней службе, такой как https://www.ipify.org / которая могла бы отражать IP-адрес таким, каким он виден из внешнего мира
... но эти идеи полностью отличаются от первоначального вопроса. :)
Ответ 4
В качестве псевдонима называется myip:
alias myip="python -c 'import socket; print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith(\"127.\")][:1], [[(s.connect((\"8.8.8.8\", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])'"
Корректно работает с Python 2.x, Python 3.x, современными и старыми дистрибутивами Linux, OSX / macOS и Windows для поиска текущего IPv4-адреса.
Не вернет правильный результат для машин с несколькими IP-адресами, IPv6, без настроенного IP-адреса или без доступа в Интернет.
Как сообщается, это не работает в последних версиях macOS.
ПРИМЕЧАНИЕ: Если вы собираетесь использовать что-то подобное в программе на Python, правильный способ - использовать модуль Python, поддерживающий IPv6.
То же, что и выше, но только код на Python:
import socket print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] ifnot ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
Это вызовет исключение, если IP-адрес не настроен.
Версия, которая также будет работать в локальных сетях без подключения к Интернету:
import socket print((([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] ifnot ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0])
Использование socket.gethostbyname(socket.gethostname()) здесь не сработало, потому что на одном из компьютеров, на которых я был, был /etc/hosts с дублирующимися записями и ссылками на самого себя. socket.gethostbyname() возвращает только последнюю запись в /etc/hosts.
Это была моя первая попытка, которая отсеивает все адреса, начинающиеся с "127.":
import socket print([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] ifnot ip.startswith("127.")][:1])
Это работает с Python 2 и 3 в Linux и Windows, но не работает с несколькими сетевыми устройствами или IPv6. Однако в последних дистрибутивах Linux это перестало работать, поэтому я попробовал этот альтернативный метод. Он пытается подключиться к DNS-серверу Google по адресу 8.8.8.8 через порт 53:
import socket print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])
Этот метод также работает в последних версиях macOS!
Затем я объединил два вышеперечисленных метода в однострочный, который должен работать везде, и создал myip псевдоним и фрагмент Python вверху этого ответа.
С ростом популярности IPv6 и для серверов с несколькими сетевыми интерфейсами использование модуля Python сторонних производителей для поиска IP-адреса, вероятно, является более надежным, чем любой из перечисленных здесь методов.