我正在玩Python(2.7.4)中的切片:
class Foo():
def __getitem__(self, key):
# Single value
if isinstance(key, (int,long)):
return key
# Slice
if isinstance(key, slice):
print 'key.start = 0x{0:X} key.stop = 0x{1:X}'.format(key.start, key.stop)
length = key.stop - key.start
return str(length)
一切似乎都按预期工作:
>>> f = Foo()
>>>
>>> f[42]
42
>>>
>>> f[20:30]
key.start = 0x14 key.stop = 0x1E
'10'
除了切片索引似乎限于0x7FFFFFFF:
>>> f[0xFEDCBA98 : 0xFFFFFFFF]
key.start = 0x7FFFFFFF key.stop = 0x7FFFFFFF
'0'
>>> f[0x80000000:0x90000000]
key.start = 0x7FFFFFFF key.stop = 0x7FFFFFFF
'0'
为什么切片索引不会与常规long
值相同的int
整数提升?有没有解决方法呢?
答案 0 :(得分:7)
我意识到这似乎是旧式课程的限制。 New-style classes(源自object
的行为)符合预期:
class Foo(object):
#...
结果:
>>> f = Foo()
>>>
>>> f[0x80000000:0x90000000]
key.start = 0x80000000 key.stop = 0x90000000
'268435456'
>>>
>>> f[0xFEDCBA98 : 0x1200000000]
key.start = 0xFEDCBA98 key.stop = 0x1200000000
'73033532776'
>>>
我没有在任何地方看到过这种情况。这特别令人困惑,因为这个限制不在slice
类本身:
>>> s = slice(0xFEDCBA98, 0x1200000000)
>>>
>>> s
slice(4275878552L, 77309411328L, None)
>>>
>>> hex(s.start)
'0xfedcba98L'
答案 1 :(得分:7)
经过大量搜索,我找到了这个
在python 3.3中,切片的开始和结束类似于this
start = PyLong_FromSsize_t(istart);
...
end = PyLong_FromSsize_t(istop);
但是在2.7中它们被发现像this
start = PyInt_FromSsize_t(istart);
...
end = PyInt_FromSsize_t(istop);
在2.7中,PyInt_FromSsize_t
最终使用long
的大小,其中3.3 PyLong_FromSsize_t
使用PyObject
的大小。这就是为什么它在3.3而不是在2.7中工作正常。