我允许用户上传 CSV 或 Excel 文件。我正在使用 pandas 读取文件并创建数据框。由于我无法预测用户将上传哪种文件类型,因此我将 pd.read_csv() 和 pd.read_excel() 包装在 try/ except 块中。
if form.validate_on_submit():
input_filename = secure_filename(form.file.data.filename)
try:
df = pd.read_csv(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
except:
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
如果 pd.read_csv() 位于 try/ except 块中的第一个我上传了一个 .csv 文件,它可以工作。如果我尝试上传 .xlsx 文件,则会收到此错误:
TypeError: expected str, bytes or os.PathLike object, not NoneType
如果 pd.read_excel() 位于 try/ except 块中的第一个并且我上传 .xlsx 文件,则它可以工作。如果我尝试上传 .csv 文件,则会收到此错误:
pandas.io.common.EmptyDataError: No columns to parse from file
以前,我使用 mimetype 将文件路由到正确的 pandas 函数,但我希望有一个更干净(且包罗万象)的解决方案,但没有涉及多个 if/elif 语句。这就是我的:
if form.file.data.mimetype == 'text/csv':
df = pd.read_csv(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
elif form.file.data.mimetype == 'application/octet-stream':
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
elif form.file.data.mimetype == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
df = pd.read_excel(form.file.data, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
else:
flash('Error Uploading File. Invalid file type. Please use xls, xlsx or csv.', 'danger')
return render_template('upload.html', current_user=current_user, form=form)
我正在使用 Flask、WTForms 和 Python 3。谢谢。
的尝试/异常方法的问题在于,不处理引发异常的特定异常类型。引发
TypeError
或
EmptyDataError
可能有很多原因,并且盲目地尝试其他函数可能并不总是合适的解决方案。
这是一个更强大的解决方案,它首先保存上传的文件,然后根据文件扩展名使用适当的 Pandas 函数:
import os
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = {'csv', 'xlsx', 'xls'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['GET', 'POST'])
def upload():
form = UploadForm()
if form.validate_on_submit():
file = form.file.data
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath)
try:
if filename.endswith('.csv'):
df = pd.read_csv(filepath, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
elif filename.endswith(('.xlsx', '.xls')):
df = pd.read_excel(filepath, header=0, skip_blank_lines=True, skipinitialspace=True, encoding='latin-1')
else:
flash('文件类型不受支持。', 'danger')
return redirect(request.url)
# 在此处处理数据框 (df)
except Exception as e:
flash(f'上传文件时出错:{e}', 'danger')
return redirect(request.url)
return redirect(url_for('success'))
else:
flash('文件类型无效。请使用 xls、xlsx 或 csv。', 'danger')
return render_template('upload.html', form=form)
说明:
-
允许的文件:
使用集合
ALLOWED_EXTENSIONS
定义允许的文件扩展名,以提高安全性。 -
辅助函数
allowed_file
: 此函数检查上传的文件名是否具有允许的扩展名。 -
保存文件:
上传的文件首先使用
file.save(filepath)
保存到服务器。 -
基于扩展名的处理:
文件保存后,代码会检查文件扩展名,并使用
pd.read_csv()
或pd.read_excel()
来读取文件。 -
错误处理:
try...except
块捕获文件读取过程中可能发生的任何错误,并向用户显示消息。
此方法比仅依赖异常处理更可靠、更安全,因为它可以确保使用正确的方法来读取文件,并且不会意外地尝试使用错误的函数读取无效文件。
标签:python,python-3.x,pandas From: 41747970