【问题标题】:Python - Indent on a Return StatementPython - 在返回语句上缩进
【发布时间】:2021-12-31 17:50:48
【问题描述】:

我正在稍微修改我不久前编写的旧函数以生成报告。最初,生成的报告被路由到指定的路径供用户获取,但我决定尝试让用户选择在请求点也下载报告(通过合并 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 个。除了 Exhibit_A 中的 2 个空白文件之外,两个函数的报告看起来都完好无损。我希望得到关于 Exhibit_A 奇怪行为的一些反馈。

ADDENDUM:Exhibit_B 可能是最佳实践,但我认为 Exhibit_A 应该也可以工作,因为“AAA”变量在“for-loop 序列”之外,它确实有效 - 但是不是所有的时间。反馈表示赞赏。谢谢。

【问题讨论】:

    标签: python flask sqlalchemy export-to-csv


    【解决方案1】:

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

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

    (编辑)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)
    

    【讨论】:

    • 所以上下文管理器不能保证在返回时点击__exit__?不像try/finally?哦,我想我明白了:sendfile 正在在上下文中加载文件
    • 我认为它在return 之前命中,但在send_file 之前不是
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 2019-08-01
    • 2014-01-17
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多