"return"语句后是否可以删除一条记录?

Is it possible to delete a record after "return" statement?

我在 'hr.contract' 中创建了一个生成工资单的函数。但是这个工资单是用来模拟和计算一些工资的,所以创建工资单后我必须删除它。

此外,我还制作了一个功能,可以从合同表格中打印工资单报告。问题是,当我单击“打印”按钮时,我创建了工资单和 return 它的报告,但后来我想不出删除创建的工资单的方法。

def generate_report(self):
        # I get this values from another methods,
        # I put 1 and 20 just to avoid confution in the question.
        run_id = 1
        indicador_id = 20

        payslip = self.generate_fake_nominee(run_id, self.employee_id.id, indicador_id, self.id)

        report = payslip.print_nominee_report()
        return report

我在 return 之后无法做任何事情,有什么想法吗?

假设payslip是唯一的引用,在函数returns时应该删除。如果它持有可能无法正确清理的资源,则:

  1. 它应该实现上下文管理协议,并且可以使用 with 语句:

    with self.generate_fake_nominee(run_id, self.employee_id.id, indicador_id, self.id) as payslip:
        return payslip.print_nominee_report()
    

    或者,

  2. 如果需要手动调用一些清理函数,可以使用finally块:

    payslip = self.generate_fake_nominee(run_id, self.employee_id.id, indicador_id, self.id)
    try:
        return payslip.print_nominee_report()
    finally:
        payslip.cleanup_function()
    

明确地说,将 del payslip 放在 finally 块中是完全没有意义的;无论如何,当函数 returns 时,名称将被解除绑定,因此 del 什么也做不了。要么绑定到 payslip 的对象无论如何都会被释放(如果它没有其他别名),要么它无论如何都不会被释放(它在别处有别名)。当函数 returns 无论如何,payslip 是未绑定的,而 del 所做的只是明确解除绑定,这更慢且毫无意义的冗长。


更新: 看来您原始代码中的 reportpayslip 对象具有实时依赖性,因此您实际上无法清理向上 payslip 直到调用者完成报告。如果是这样,您还有两个选择:

  1. 找出如何删除实时依赖项,因此 report 是一组独立的数据(取决于您未向我们展示的代码,但这是可能的最佳解决方案)

  2. 使用绑定到 report 的终结器保留 payslip 直到 report 被垃圾收集,此时它会清理它,a la:

    # At top of module
    import weakref
    
    def generate_report(self):
        # I get this values from another methods,
        # I put 1 and 20 just to avoid confution in the question.
        run_id = 1
        indicador_id = 20
    
        payslip = self.generate_fake_nominee(run_id, self.employee_id.id, indicador_id, self.id)
    
        report = payslip.print_nominee_report()
        # Ensure cleanup_function is called when report is gc-ed
        weakref.finalize(report, payslip.cleanup_function)
        return report
    

    这个选项并不完美;即使在具有确定性引用计数的 CPython 上,如果涉及到引用循环,即使您已完成 report,在调用循环收集器并实际收集 report 之前也可能需要任意时间(并调用清理功能)。在具有真正垃圾收集器的非 CPython 解释器上,即使没有引用循环也会发生这种情况。