我写这篇文章是为了获得Linux上网络接口的列表。在过去,我使用了一些公开可用的方法,比如ActiveState,它使用ioctl,在Python3下工作很烦人,这个版本只是在ifconfig的输出上使用正则表达式。
这里使用的文档样式遵循numpy文档指南。
#!/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))发布于 2015-09-12 12:11:53
这是一个巨大的docstring,它比代码本身长。您应该阅读Python的关于如何编写好的文档字符串的PEP。
首先,docstring不应该包含示例,如果需要,可以将其作为常规注释放在脚本中。而且,您不需要对参数的类型和可选性质如此详细和明确。我会从您的参数中提取一些信息,并返回部分,然后将其折叠回您的开始部分。文档字符串应该是相对简洁的,主要是添加上下文和解释。
用户可以很容易地看到默认参数get_interfaces(external=False, ip=False),这表明它们是可选的和布尔值。你只需要解释一下设置它们会产生什么影响。
发布于 2018-10-09 15:26:43
解析ifconfig的输出是有问题的:不同版本的输出格式略有不同,很难使代码具有足够的灵活性来处理它们。一般来说,也不可能处理未来的输出格式。
您最好使用ip addr,它具有更一致和更可预测的输出格式。
文档字符串中的doctest用例不是很好的单元测试--在编写本报告时,它们可能对您的机器是正确的,但是它们太脆弱了,因为它们依赖于您无法控制的环境。
https://codereview.stackexchange.com/questions/104504
复制相似问题