我正在使用pythons ipaddress模块,我试图只获得第一个可用的主机,而不是所有可用的主机
下面给了我所有主机,当我尝试索引它时,我得到以下错误。
是否可以通过任何其他方式获得第一个可用的主机?
由于
n = ipaddress.ip_network(u'10.10.20.0/24')
for ip in n.hosts():
... print ip
10.10.20.1
10.10.20.2
10.10.20.3
10.10.20.4
...
>>> for ip in n.hosts():
... print ip[1]
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
TypeError: 'IPv4Address' object does not support indexing
>>>
以下也失败了
>>> print n.hosts()[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'generator' object has no attribute '__getitem__'
答案 0 :(得分:4)
hosts()
返回一个不支持索引的生成器对象。你必须遍历它。
如果您只想要第一个元素,只需使用next()
:
n = ipaddress.ip_network(u'10.10.20.0/24')
first_host = next(n.hosts())
如果要将生成器对象转换为支持索引的列表,则必须调用list()
函数:
all_hosts = list(n.hosts())
first_host = all_hosts[0]
您也可以像在列表中一样遍历生成器对象,就像在第一个代码段中一样:
for ip in n.hosts():
# do something with ip: this is the IP address, so don't try to index into it!
pass
答案 1 :(得分:1)
简短版本:
import ipaddress
net=ipaddress.ip_network(u'1.0.0.0/8')
first=str(net[1])
last=str(net[-2])
长版:
这显示了计算第一个和最后一个可用IP地址的3种方法 在使用ipaddress的CIDR块中。
显示&#34;右&#34; (快速,节省空间的方式) 和另外两个使用主机迭代器的结果 说明了经典的时空权衡。
import ipaddress
import time
import sys
#
# The fast, memory efficient way
#
start = time.time()
net=ipaddress.ip_network(u'1.0.0.0/8')
first=str(net[1])
last=str(net[-2])
stop = time.time()
seconds=stop-start
size=sys.getsizeof(net)
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
#
# Space efficient, but slow
#
start = time.time()
net=ipaddress.ip_network(u'1.0.0.0/8')
iterator=ipaddress.ip_network(u'1.0.0.0/8').hosts()
first = last = next(iterator, None)
for last in iterator:
pass
first=str(first)
last=str(last)
stop = time.time()
seconds=stop-start
size=sys.getsizeof(net)
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
#
# Memory hog and slow, the worst of both worlds.
#
start = time.time()
hosts=list(ipaddress.ip_network(u'1.0.0.0/8').hosts())
first_host=str(hosts[0])
last_host=str(hosts[-1])
size=sys.getsizeof(hosts)
stop = time.time()
seconds=stop-start
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 0.0000, Size (Mb): 0
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 8.0086, Size (Mb): 0
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 11.8096, Size (Mb): 132
答案 2 :(得分:0)
获取第一个主机地址的替代方式,特别是“大型网络”/小前缀值:
In [2]: ip_network("10.10.20.0/24")[1]
Out[2]: IPv4Address('10.10.20.1')
根本不需要使用hosts()生成器。参见例如关于ipaddress网络对象的https://docs.python.org/3/library/ipaddress.html#networks-as-containers-of-addresses为“地址容器”。该地址空间/“地址容器”中的第一个地址是网络地址(索引[0])。最后一个地址是广播地址(索引[-1])。
或者您可以使用网络地址&amp;通过添加1来获取第一个主机地址:
In [4]: ip_network("10.10.20.0/24").network_address + 1
Out[4]: IPv4Address('10.10.20.1')
根据您使用的前缀/网络掩码, hosts()生成器可能很慢。如果你使用
list(ip_network("10.0.0.0/8").hosts())
该语句创建一个包含2 **(32-8) - 2 = 16777214条目的列表
如果我对此陈述进行评估,则需要&gt; 10秒创建此主机列表:
In [11]: %time len(list(ip_network("10.0.0.0/8").hosts()))
Wall time: 13.6 s
Out[11]: 16777214
如果我比较获得第一个地址所需的时间:
In [15]: %time list(ip_network("10.0.0.0/8").hosts())[0]
Wall time: 13.6 s
Out[15]: IPv4Address('10.0.0.1')
In [13]: %timeit -n10 -r5 ip_network("10.0.0.0/8")[1]
10 loops, best of 5: 11.8 µs per loop
In [17]: %timeit -n10 -r5 ip_network("10.0.0.0/8").network_address + 1
10 loops, best of 5: 9.16 µs per loop
结果:hosts()需要大约14秒才能完成。替代方案是+/-10μs
/ 24网络的时间:
In [19]: %timeit -n10 -r5 list(ip_network("10.0.0.0/24").hosts())[0]
10 loops, best of 5: 135 µs per loop
In [20]: %timeit -n10 -r5 ip_network("10.0.0.0/24").network_address + 1
10 loops, best of 5: 9.32 µs per loop