简体   繁体   中英

Python IndexError: list index out of range. Cannot access by index

I am using pySerial to read TTL byte stream. To read two bytes:

CheckSumByte = [ b for b in ser.read(2)]
print( CheckSumByte)
print( type(CheckSumByte))
print( str(len(CheckSumByte)))
print( CheckSumByte[0])

Output:

[202, 87]
<class 'list'>
2
IndexError: list index out of range

I cannot access any elements of CheckSumByte by index (0 or 1). What is wrong?

Here is my code:

while(ReadBufferCount < 1000):
    time.sleep(0.00002)
    InputBuffer = ser.inWaiting()
    if (InputBuffer > 0):
        FirstByte = ser.read(1)
        if ord(FirstByte) == 0xFA:
            while ser.inWaiting() < 21: pass
        IndexByte = ser.read(1)
        SpeedByte = [ b for b in ser.read(2)]
        DataByte0 = [ b for b in ser.read(4)]
        DataByte1 = [ b for b in ser.read(4)]
        DataByte2 = [ b for b in ser.read(4)]
        DataByte3 = [ b for b in ser.read(4)]
        CheckSumByte = [ b for b in ser.read(2)]
        print( CheckSumByte[0]) #Out of Range??`
Traceback (most recent call last):

  File "<ipython-input-6-5233b0a578b1>", line 1, in <module>
    runfile('C:/Users/Blair/Documents/Python/Neato XV-11 Lidar/Serial9.py', wdir='C:/Users/Blair/Documents/Python/Neato XV-11 Lidar')

  File "C:\Program Files (x86)\WinPython-32bit-3.4.3.3\python-3.4.3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 682, in runfile
    execfile(filename, namespace)

  File "C:\Program Files (x86)\WinPython-32bit-3.4.3.3\python-3.4.3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 85, in execfile
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)

  File "C:/Users/Blair/Documents/Python/Neato XV-11 Lidar/Serial9.py", line 88, in <module>
    print( CheckSumByte[0]) #Out of Range??

IndexError: list index out of range

Kenny: Thanks. Even simpler for the two bytes:

    CheckSumByte.append(ser.read(1))
    CheckSumByte.append(ser.read(1))

Works properly, but awkward. The items are type bytes. How to add items to the list using list comprehension? I would like to avoid the append function because it is slow.

I notice it does not work when the items of CheckSumByte are integer. Does Python 3 list comprehension require special format to add the bytes as byte (not convert to integer)?

According to your most recent comment you have constructed ser as:

ser = serial.Serial(
    port=PortName, baudrate=115200, parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, 
    timeout=0)

According to the documentation this means that ser is non-blocking (despite your assertion it is blocking!).

As it is in non-blocking mode there is absolutely no reason to expect ser.read(n) to return exactly n bytes. Instead, if you wish to read n bytes you should either:

  • construct ser as blocking (use timeout=None ) in the constructor; or
  • loop while monitoring the number of bytes actually read (just as you would when reading a network socket)

The latter for example means that if you wish to read n bytes you will need to do something like:

def read_exactly(ser, n):
    bytes = b""

    while len(bytes) < n:
        bytes += ser.read(n - len(bytes))

    return bytes

In your particular case, you seem to be monitoring the the input buffer to ensure there is adequate data for the following reads. But this monitoring is only occurring some of the time, not all of the time. Thus when FirstByte != 0xFA you could exhaust the read buffer unless you take one of the approachs given above.

donkopotamus - You found the answer. I confused the blocking terms. I set timeout=0 to try other setup. You are right, ser could read zero bytes. I forgot to set it back to timeout=None. Now always reads some bytes. No more IndexError. Thank you very much.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM