Python中的断言失败
我有这段代码:
/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' 不是十六进制字符,所以只有在你有很长的字符串时才会出现。