我挑战你在函数返回之前为“del”找到一个合理的用例

I challenge you to find a reasonable-ish use case for `del` before function return

提问人:Rami Luisto 提问时间:9/22/2023 更新时间:9/22/2023 访问量:50

问:

我目前正在使用一个由我之前的六个人开发的遗留系统,每个人都修复了问题并添加了新功能,而没有为“代码审查”、“文档”或“风格指南”等愚蠢的事情而烦恼。在我之前的人也拥有非常不同的编码专业知识水平,因此由此产生的代码库可以被描述为“丰富多彩”,因为缺乏更好的术语。

因此,代码库充满了普通代码、聪明的位、出色的黑客和可怕的意大利面条脚本。哪个是哪个并不总是很明显的。代码中我最喜欢的谜题之一在功能上如下所示:

def main_function(text, number):
    check_flag, squared_number = auxiliary_function(number)
    if check_flag == False:
        error = "Number could not be squared."
        return False, error

    combined_data = text + str(squared_number)

    del check_flag
    return True, combined_data


def auxiliary_function(number):
    try:
        result = number * number
        return True, result
    except Exception as e:
        return False, number


if __name__ == "__main__":
    text = "Hello, world! "
    number = 42
    check_flag, result = main_function(text, number)
    print(result)

    text = "Hello, world! "
    number = "42"
    check_flag, result = main_function(text, number)
    print(result)

现在,即使在这个小片段中也有很多事情发生,其中大部分不是很 Pythonic,但我真正想关注的是回归之前的部分。为什么我称其为谜题而不是明显多余的代码?原因是到目前为止,到目前为止,这个项目中基本上每一段奇怪的代码,我都能够通过弄清楚什么样的边缘情况可以使给定的方法在理论上可行,或者通过研究足够的 Python 机制来了解为什么给定的代码永远无法按预期工作。del check_flagmain_function

但是在这里,由于我对命令、函数范围基础知识和 Python 垃圾回收缺乏了解,我有点陷入困境。(在过去的几年里,我想我有过一次合理的使用案例,尽管我本可以通过更流畅地使用 Pandas 库来避免这种情况。deldel

在研究了函数作用域的工作原理之后,似乎函数作用域内的任何事物(基元或对象)的唯一情况是,如果要删除的事物被迫具有更宽的范围,例如,使用 。因此,从理论上讲,这可以用于我想要一个全局标志变量的情况,该变量使我能够使用具有 和 的值的三级逻辑。(我知道,这很牵强,很可怕。deldelglobalTrueFalseNameError

我知道有时坏代码只是坏代码,但我仍然想问一下是否有人可以弄清楚任何复杂的设置,例如在复杂的对象继承、异步函数或其他“在函数返回之前”实际上甚至可能是一件边缘合理的事情?或者,或者,函数作用域是否有一些基本的东西可以排除除删除更大作用域中的对象之外的任何其他内容?del

python 垃圾回收 del

评论

2赞 Anentropic 9/22/2023
这看起来只是一段废话代码,散发着一股糟糕的代码气味。 只是一个布尔值 var,它不可能做任何有用的事情check_flagdel
2赞 Kelly Bundy 9/22/2023
只需 git 责备该行并阅读提交消息/PR/问题 :-)。“原语”是什么意思?
1赞 user19077881 9/23/2023
在函数退出时删除堆栈帧时,局部变量将丢失。所以这个代码行没有价值;也许是某种现在被遗忘的意图的产物,或者只是被误导了。
0赞 Rami Luisto 9/23/2023
是的,也许我太希望在这段代码中找到珍珠了,^^ @KellyBundy我指的是我们在这里删除一个布尔值,在我看来,它适合 int、float 和 str 等基元集,它们的行为可能与更复杂的对象(如函数或对象)不同。(虽然我猜在 Python 中差异并不大。
1赞 Kelly Bundy 9/23/2023
不过,bools、ints、floats 和 strs 都是对象。“基元或对象”并没有真正的意义。

答:

1赞 Alain T. 9/22/2023 #1

我什至没有一个好的“坏”理由在布尔值上这样做。然而,鉴于该代码的历史,它可能是一些未正确清理的实验的残余。例如,如果代码在事后执行某些操作(它不是,但可能在早期的化身中),可能会有一些牵强的逻辑来确定在此过程中分配了哪些局部变量,这将在使用它之前从 locals() 中排除该标志。locals()