Python FTP检索中断FOR循环,添加try-except后恢复,求原因
ftp.retrbinary break my FTP directory traversal loop in Python? Let's break down exactly what's happening here, based on your code and scenario:
The Root Cause
Your original code wraps the entire FTP workflow in a single broad try...except block. When ftp.retrbinary hits an error (for any reason), that exception gets caught by the outer except clause, which immediately prints "Could not connect to ftp device" and exits the entire program—stopping your loop dead in its tracks.
When you run commands one-by-one in the terminal, individual errors don't kill the whole process; you just get an error message for that single command and can keep going. That's why you didn't see the issue there.
What's Triggering the retrbinary Error?
There are a few likely culprits with your robot's FTP server:
- Permission restrictions: Some files or directories on the robot might be locked down, and your user account can't retrieve them.
nlstreturning directories: Many embedded/industrial FTP servers (like your robot's) include subdirectories innlstoutput. Trying to "download" a directory withretrbinarywill throw an error.- Race conditions: A file might get deleted or moved between the time you run
ftp.nlst()andftp.retrbinary(). - Temporary network issues: A blip in the connection mid-download could cause a failure.
Why Adding a Local try-except Fixes It
By wrapping just the ftp.retrbinary call in its own try...except, you contain the error to that single file. If downloading one file fails, the exception is caught locally, you skip over it with pass, and the loop continues to the next file (and eventually the next folder). The error no longer bubbles up to the outer except that was killing your entire script.
Quick Robustness Improvements
To make your script more reliable and debuggable:
- Avoid empty
exceptclauses: Catch specific exceptions instead of swallowing all errors blindly. This lets you log exactly what went wrong with specific files:from ftplib import FTP, error_perm # ... try: ftp.retrbinary('RETR '+ filename, file.write) except error_perm: print(f"Permission denied when downloading {filename}") except IOError as e: print(f"IO error downloading {filename}: {e}") - Check if entries are files before downloading: Use
ftp.mlsd()instead ofnlst()to get file type metadata, so you don't waste time trying to download directories:for entry in ftp.mlsd(): filename, attrs = entry if attrs['type'] == 'file': # Proceed with download logic here - Narrow your outer
except: The broad outerexcepthides useful errors like failed logins or invalid paths. Catch specific exceptions there too, likeftplib.all_errors.
内容的提问来源于stack exchange,提问作者Sayade

