Python中的断言失败

1 投票
2 回答
1056 浏览
提问于 2025-04-17 13:40

我有这段代码:

/server/frontend/wsn.py
Line 866:        
    netid = hextransform(int(nid), 16)

Line 156: 
    def hextransform(data, length):
        data = hex(data)[2:]
        assert(len(data) <= length)
        # zero-padding
        data = ('0' * (length - len(data))) + data
        # Swap 'bytes' in the network ID
        data = list(data)
        for i in range(0, length, 2):
            tmp = data[i]
            data[i] = data[i + 1]
            data[i + 1] = tmp
        # Reverse the whole string (TODO: CHECK) 
        data.reverse()
        #data = "".join(data)
        return data

我的问题是,当我有一个 nid = 15579202759033880576 这样的数字时,它是不是太长了?

我从Tornado收到的错误信息是:

Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/tornado/web.py", line 988, in _execute
    getattr(self, self.request.method.lower())(*args, **kwargs)
  File "/usr/lib/python2.6/site-packages/tornado/web.py", line 1739, in wrapper
    return method(self, *args, **kwargs)
  File "./wsn.py", line 866, in get
    netid = hextransform(int(nid), 16)
  File "./wsn.py", line 158, in hextransform
    assert(len(data) <= length)
AssertionError

但是 netid 转换成十六进制是 0xd834725e00000000,而且 len(nid) = 16

我不知道问题出在哪里。

2 个回答

2

在Python中,长数字会加一个L

>>> hex(int(15579202759033880576))
'0xd834725e00000000L'

这只是多了一个字符。你可以用另一种方法来创建十六进制数字:

format(data, '016x')

而不是直接写。format()函数可以让你使用格式说明的小语言来转换你的数据;在这个例子中,x是小写的十六进制表示,而且你不需要切片:

>>> format(15579202759033880576, '016x')
'd834725e00000000'

注意格式中的016;如果你的数字小于16个十六进制位,它会自动用零填充:

>>> format(1557920, '016x')
'000000000017c5a0'

你的字节交换也可以更简单;Python支持多重赋值,这样你可以在不需要临时变量的情况下交换两个值:

for i in range(0, length, 2):
    data[i], data[i + 1] = data[i + 1], data[i]

因此,你的hextransform方法可以简化为:

def hextransform(data, length):
    data = format(data, '0{0}x'.format(length))
    assert(len(data) == length), '{0!r}, {1}'.format(data, length)
    # Swap 'bytes' in the network ID
    data = list(data)
    for i in range(0, length, 2):
        data[i], data[i + 1] = data[i + 1], data[i]
    data.reverse()
    return data

最终结果是:

>>> hextransform(15579202759033880576, 16)
['0', '0', '0', '0', '0', '0', '0', '0', '5', 'e', '7', '2', '3', '4', 'd', '8']
1

你遇到的问题是来自于 hex(int(num)) 这个结果中的 'L' 字母:

>>> hex(int(15579202759033880576))[2:]
'd834725e00000000L'   <-- 17 with the L

解决这个问题最快的方法就是更新你的字符串处理方式,把那个 'L' 去掉:

data = hex(data)[2:].split('L')[0]

这样做会把你的字符串在 'L' 的地方切开(如果有的话),然后只保留十六进制的部分。这样做是安全的,因为 'L' 不是十六进制字符,所以只有在你有很长的字符串时才会出现。

撰写回答