Python - 在 Return 语句上缩进

Python - Indent on a Return Statement

我正在对前一段时间编写的旧函数进行轻微修改以生成报告。最初,生成的报告被路由到指定路径供用户去取,但我决定尝试为用户提供在请求时也可以下载报告的选项(通过合并 send_file)。因此下面的代码块。

附件 A

@VVV.route("/reports/users")
def users_report():
    if not session.get("logged_in"):
        return render_template("login.html")
    else:
        suffix = datetime.now()
        suffix2 = str(suffix)
        suffix3 = suffix2.split(" ")
        suffix4 = suffix.strftime('%H%M%S')
        with open(r'<path>\tahnreports_sysusers_%s_%s.csv' %(suffix3[0],suffix4), 'w', newline='') as start_key:
            #newline parameter avoids the extra line space between rows in the csv.

            csv_header = ("WID", "F_NAME", "L_NAME", "ORG_ROLE", "ORG_STATUS", "SYS_LOGIN_ID")
            csv_out_01 = csv.writer(start_key)
            csv_out_01.writerow(csv_header)
            x15 = divo.session.query(pearl.work_id, pearl.user_fname, pearl.user_lname, pearl.user_category, pearl.user_status,
                                    pearl.login_id)
            for i in x15:
                csv_out_02 = csv.writer(start_key)
                csv_out_02.writerow(i)
            AAA = (r'<path>\tahnreports_sysusers_%s_%s.csv' %(suffix3[0],suffix4))
            return send_file(AAA, as_attachment=True)

附件 B:

@VVV.route("/reports/users")
def users_report():
    if not session.get("logged_in"):
        return render_template("login.html")
    else:
        suffix = datetime.now()
        suffix2 = str(suffix)
        suffix3 = suffix2.split(" ")
        suffix4 = suffix.strftime('%H%M%S')
        with open(r'<path>\tahnreports_sysusers_%s_%s.csv' %(suffix3[0],suffix4), 'w', newline='') as start_key:
            #newline parameter avoids the extra line space between rows in the csv.

            csv_header = ("WID", "F_NAME", "L_NAME", "ORG_ROLE", "ORG_STATUS", "SYS_LOGIN_ID")
            csv_out_01 = csv.writer(start_key)
            csv_out_01.writerow(csv_header)
            x15 = divo.session.query(pearl.work_id, pearl.user_fname, pearl.user_lname, pearl.user_category, pearl.user_status,
                                    pearl.login_id)
            for i in x15:
                csv_out_02 = csv.writer(start_key)
                csv_out_02.writerow(i)
            AAA = (r'<path>\tahnreports_sysusers_%s_%s.csv' %(suffix3[0],suffix4))
    return send_file(AAA, as_attachment=True)

我的问题是试图理解为什么这两个代码块的行为不同。下面的两个函数除了一个小区别外是相同的——return 语句的缩进。虽然它们都生成并提示用户下载报告,但 Exhibit_A 有时会生成一个空文件,而 Exhibit_B 总是会生成真实的报告。我认为这与 return 语句的缩进有关,但我似乎不太相信它。

进一步阐述这个问题。我使用这两个函数分别生成了 10 次报告。 Exhibit_A 生成了 10 份报告中的 8 份,其中 2 份是空白文件,而 Exhibit_B 生成了 10 份报告中的 10 份。除了来自 [=42= 的 2 个空白文件外,这两个函数的报告看起来都完好无损].我希望得到 Exhibit_A.

对奇怪行为的一些反馈

ADDENDUM:Exhibit_B 可能是最佳实践,但我的想法是 Exhibit_A 也应该有效,因为“AAA”变量在'for-loop sequence',它确实有效——但不是一直有效。反馈表示赞赏。谢谢。

在 A 中,您在 with 上下文中调用 send_file,这意味着文件仍处于打开状态以供写入,并且可能尚未刷新到磁盘(或可读)。

在 B 中,您等到 with 结束(因此文件已关闭),然后再调用 send_file

(edit) FWIW,以下是我为提高可读性而清理它的方法——else 添加的额外级别的缩进使得 with 的细微之处更难被发现,而且所有额外的变量也无济于事。乍一看,您在 send_file 中发送的文件与您正在编写的文件相同,这对我来说并不明显,因为构建文件路径的表达式过于复杂,并且在两个地方复制粘贴.每行都有不同的作者也很混乱——我认为这没有什么坏处,但我也不认为它会增加任何好处。

@VVV.route("/reports/users")
def users_report():
    if not session.get("logged_in"):
        return render_template("login.html")

    output_path = (
        r'<path>\tahnreports_sysusers_%s.csv'
        % datetime.now().strftime('%Y-%m-%d_%H%M%S')
    )
    with open(output_path, 'w', newline='') as file:
        csv_out = csv.writer(file)
        csv_out.writerow((
            "WID",
            "F_NAME",
            "L_NAME",
            "ORG_ROLE",
            "ORG_STATUS",
            "SYS_LOGIN_ID"
        ))  # header
        csv_out.writerows(divo.session.query(
            pearl.work_id,
            pearl.user_fname,
            pearl.user_lname,
            pearl.user_category,
            pearl.user_status,
            pearl.login_id
        ))  # data
    return send_file(output_path, as_attachment=True)