首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Linux上获取网络接口

问在Linux上获取网络接口
EN

Code Review用户
提问于 2015-09-12 11:13:40
回答 2查看 5.7K关注 0票数 5

我写这篇文章是为了获得Linux上网络接口的列表。在过去,我使用了一些公开可用的方法,比如ActiveState,它使用ioctl,在Python3下工作很烦人,这个版本只是在ifconfig的输出上使用正则表达式。

这里使用的文档样式遵循numpy文档指南。

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Get a list of network interfaces on Linux.

This code is compatible with Python versions 2 and 3.

"""
from collections import namedtuple
import re
import subprocess


def get_interfaces(external=False, ip=False):
    """
    Get a list of network interfaces on Linux.

    To access the MAC address and/or the IP address, set the relevant keyword
    arguments to True.

    Parameters
    ----------
    external : bool, optional
        Only show external interfaces, and ignore virtual (e.g. loopback)
        devices, and return their MAC addresses.
    ip : bool, optional
        Only show interfaces which are UP and have an IP address, and return
        their IPv4 addresses.

    Returns
    -------
    interfaces
        list of str containing the interface name by default, or list of
        namedtuple containing `name`, `mac`, and `ip` as requested.

    Examples
    --------
    >>> print(get_interfaces())
    ['eth0', 'lo', 'wlan0']
    >>> print(get_interfaces(external=True))
    [Interface(name='eth0', mac='a0:b1:c2:d3:e4:f5'), Interface(name='wlan0', ma
    c='f5:e4:d3:c2:b1:a0')]
    >>> print(get_interfaces(ip=True))
    [Interface(name='lo', ip='127.0.0.1'), Interface(name='wlan0', ip='192.168.1
    1.2')]
    >>> print(get_interfaces(external=True, ip=True))
    [Interface(name='wlan0', mac='f5:e4:d3:c2:b1:a0', ip='192.168.11.2')]

    """
    name_pattern = "^(\w+)\s"
    mac_pattern = ".*?HWaddr[ ]([0-9A-Fa-f:]{17})" if external else ""
    ip_pattern = ".*?\n\s+inet[ ]addr:((?:\d+\.){3}\d+)" if ip else ""
    pattern = re.compile("".join((name_pattern, mac_pattern, ip_pattern)),
                         flags=re.MULTILINE)

    ifconfig = subprocess.check_output("ifconfig").decode()
    interfaces = pattern.findall(ifconfig)
    if external or ip:
        Interface = namedtuple("Interface", "name {mac} {ip}".format(
            mac="mac" if external else "",
            ip="ip" if ip else ""))
        return [Interface(*interface) for interface in interfaces]
    else:
        return interfaces


if __name__ == "__main__":
    interfaces = get_interfaces(external=True, ip=True)
    for interface in interfaces:
        print("{name}: {ip}".format(name=interface.name, ip=interface.ip))
EN

回答 2

Code Review用户

发布于 2015-09-12 12:11:53

这是一个巨大的docstring,它比代码本身长。您应该阅读Python的关于如何编写好的文档字符串的PEP。

首先,docstring不应该包含示例,如果需要,可以将其作为常规注释放在脚本中。而且,您不需要对参数的类型和可选性质如此详细和明确。我会从您的参数中提取一些信息,并返回部分,然后将其折叠回您的开始部分。文档字符串应该是相对简洁的,主要是添加上下文和解释。

用户可以很容易地看到默认参数get_interfaces(external=False, ip=False),这表明它们是可选的和布尔值。你只需要解释一下设置它们会产生什么影响。

票数 4
EN

Code Review用户

发布于 2018-10-09 15:26:43

解析ifconfig的输出是有问题的:不同版本的输出格式略有不同,很难使代码具有足够的灵活性来处理它们。一般来说,也不可能处理未来的输出格式。

您最好使用ip addr,它具有更一致和更可预测的输出格式。

文档字符串中的doctest用例不是很好的单元测试--在编写本报告时,它们可能对您的机器是正确的,但是它们太脆弱了,因为它们依赖于您无法控制的环境。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/104504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档