Python串口发送文件至电能表遇XMODEM报错求助
Fixing AttributeError: 'str' object has no attribute 'read' in XMODEM Serial Transfer
Hey there! Let's break down what's going wrong here and fix it step by step.
The Root Cause
That error AttributeError: 'str' object has no attribute 'read' is happening because your ser variable is just a string containing the port name (like "COM3"), not an actual opened serial port object. When you call ser.read() in your getc function, Python tries to run a read() method on a string, which doesn't exist—hence the error.
The Fix
You need to initialize a proper serial port connection using serial.Serial() from the pyserial library first, instead of just storing the port name as a string. Here's the corrected code with explanations:
import serial from xmodem import XMODEM # Extract the port name from your combobox (this part was okay) port_name = serialPortCombobox.get().split(" ")[0] # Initialize the serial port with parameters matching your electricity meter # Adjust baudrate, parity, etc. to match your device's specs! ser = serial.Serial( port=port_name, baudrate=9600, # Replace with your meter's actual baud rate parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1 ) def getc(size, timeout=1): ser.timeout = timeout # Now ser is a real serial object, so read() works as expected return ser.read(size) or None def putc(data, timeout=1): ser.timeout = timeout return ser.write(data) modem = XMODEM(getc, putc) # Use try/finally to ensure we clean up resources even if an error occurs try: # Use 'with' to auto-close the file after transfer completes with open('105.8k', 'rb') as f: status = modem.send(f, retry=3) print(f"XMODEM transfer status: {status}") finally: # Always close the serial port to avoid resource leaks ser.close() # stream.close() # Remove this line if 'stream' isn't defined in your code
Key Notes to Remember
- Match Serial Parameters: Double-check that
baudrate,parity,stopbits, andbytesizeexactly match the specifications of your electricity meter. If these are incorrect, the transfer will fail even after fixing the initial error. - Resource Management: Using
withfor the file andtry/finallyfor the serial port ensures you don't leave files or ports open accidentally if something goes wrong mid-transfer. - Check Dependencies: Make sure you have
pyserialinstalled (pip install pyserial) since it's required for serial communication.
内容的提问来源于stack exchange,提问作者Shay Avitapl
相关产品推荐
相关产品推荐

