RAII是不可能的,通常将其与作用域混合使用,而当您错过这些额外的作用域时,则可能是在编写错误的代码。
也许我没有收到您的问题,或者您没有获得关于Python的一些非常重要的知识……首先,在垃圾回收语言中,与范围相关的确定性对象破坏是 不可能的 。Python中的变量仅是引用。您不希望在指向该malloc
内存free
的指针超出范围时立即对其进行存储,对吗?在 某些 情况下,如果您碰巧使用引用计数,则是实际的例外-但没有一种语言足以使确切的实现陷入僵局。
而且, 即使 您像cpython中那样具有引用计数,它也是实现细节。通常,包括在Python中有各种 不 使用引用计数的实现在内,您应该编写代码,就像每个对象都在周围徘徊,直到内存用尽。
至于在其余函数调用中存在的名称:您 可以 通过该del
语句从当前或全局范围中删除名称。但是,这与手动内存管理无关。它只是删除参考。这可能会或可能不会触发被引用对象进行GC,这不是练习的重点。
您是正确的,with
与确定范围无关,仅与确定性清理无关(因此,它最终与RAII重叠,但与手段无关)。
也许我正在尝试摆脱语言动态方面的好处。有时想要扩大范围是否自私?
不能。体面的词法作用域是独立于动态/静态的优点。诚然,Python(2-3个已基本解决)在这方面有弱点,尽管它们更多地存在于闭包领域。
但是要解释“为什么”:Python 必须 在开始新作用域的位置上保持保守,因为无需声明,否则,对名称的赋值会使它成为最内部/当前作用域的局部名称。因此,例如,如果for循环具有自己的作用域,则无法轻松地在循环外部修改变量。
我是否懒于想要编译器/解释器捕获我的疏忽变量重用错误?好吧,是的,我当然很懒,但是我会以一种不好的方式懒惰吗?
同样,我认为偶然重用名称(以引入错误或陷阱的方式)很少而且反而很少。
编辑:要尽可能清楚地再次声明: