<p>我首先创建一个包含所有空预订的列表,然后用您开始使用的非空列表覆盖它:</p>
<pre><code>#!/usr/bin/env python
reservations = [
# [DHCP SERVER, IP ADDRESS, MAC ADDRESS, HOSTNAME, DESCRIPTION]
['server1','172.16.0.120','31872fcefa33','wks120.domain.net','Description of client'],
['server1','172.16.0.125','4791ca3d7279','wks125.domain.net','Description of client'],
['server1','172.16.0.132','6035a71c930c','wks132.domain.net','Description of client'],
]
def reservationlist(reservations, serverpattern, addresspattern, hostpattern,
start, end):
result = []
for i in range(start, end + 1):
result.append([
serverpattern % i,
addresspattern % i,
'[no mac]',
hostpattern % i,
'Unregistered'])
for reservation in reservations:
index = int(reservation[1].split('.')[3]) - start
result[index] = reservation
return result
print reservationlist(
reservations,
'server%d',
'172.16.0.%d',
'wks%d.domain.net',
120,
132)
</code></pre>
<p>最终结果如下:</p>
^{pr2}$
<p>呸!我情不自禁。此版本接受起始值和结束值的IP地址:</p>
<pre><code>#!/usr/bin/env python
reservations = [
# [DHCP SERVER, IP ADDRESS, MAC ADDRESS, HOSTNAME, DESCRIPTION]
['server1','172.16.0.120','31872fcefa33','wks120.domain.net','Description of client'],
['server1','172.16.0.125','4791ca3d7279','wks125.domain.net','Description of client'],
['server1','172.16.0.132','6035a71c930c','wks132.domain.net','Description of client'],
]
def addr_to_int(address):
"""Convert an IP address to a 32-bit int"""
a, b, c, d = map(int, address.split('.'))
return a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d
def int_to_addr(value):
"""Convert a 32-bit int into a tuple of its IPv4 byte values"""
return value >> 24, value >> 16 & 255, value >> 8 & 255, value & 255
def reservationlist(reservations, serverpattern, addresspattern, hostpattern,
start, end):
reservationdict = dict((addr_to_int(item[1]), item)
for item in reservations)
startint = addr_to_int(start)
endint = addr_to_int(end)
for i in range(startint, endint + 1):
try:
item = reservationdict[i]
except KeyError:
addressbytes = int_to_addr(i)
item = [
serverpattern.format(*addressbytes),
addresspattern.format(*addressbytes),
'[no mac]',
hostpattern.format(*addressbytes),
'Unregistered']
yield item
for entry in reservationlist(
reservations,
'server{3}',
'172.16.{2}.{3}',
'wks{3}.domain.net',
'172.16.0.120',
'172.16.1.132'):
print entry
</code></pre>
<p>此版本使用<code>yield</code>关键字将<code>reservationlist()</code>转换为生成器。它不是一次保存RAM中的所有值,而是一次只发出一个值,直到循环结束。对于循环的每一次传递,它都会尝试从保留列表中获取实际值(使用<code>dict</code>快速访问)。如果不能,则使用<code>string.format</code>方法用IPv4地址字节填充字符串模板。在</p>
<h2>地址操作的速记</h2>
<p><code>int_to_addr</code>函数采用32位IP地址,如:</p>
<pre><code>AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD
</code></pre>
<p>并返回4个字节,范围为0-255,如:</p>
<pre><code>AAAAAAAA, BBBBBBBB, CCCCCCCC, DDDDDDDD
</code></pre>
<p>在该函数中,<code>>></code>表示“将值向右旋转多个位”,“amp;255”表示“只返回最后8位(128+64+32+16+8+4+2+1)”。在</p>
<p>如果我们在上面输入了“AAAA…DDDD”号码:</p>
<ul>
<li><code>value >> 24</code>=>;AAAAAAAA</li>
<li><code>value >> 16</code>=>;aaaaaaaa bbbbbb。该值&255=>;BBBBBBBB</li>
<li><code>value >> 8</code>=>;aaaaaaaa-bbbbbb-cccccccc。该值&255=>CCCCCC</li>
<li><code>value & 255</code>=>;DDDDDDDD</li>
</ul>
<p>这或多或少是将32位IPv4地址转换为4字节列表的标准方法。当你把这些值和一个点连在一起时,你会得到正常的“a.B.C.D”地址格式。在</p>