gpt4 book ai didi

python - 识别 python 函数内全局变量的无意读/写?例如使用静态分析?

转载 作者:太空宇宙 更新时间:2023-11-03 20:04:28 24 4
gpt4 key购买 nike

我对 python 感到沮丧的事情之一是,如果我编写这样的函数:

def UnintentionalValueChangeOfGlobal(a):
SomeDict['SomeKey'] = 100 + a
b = 0.5 * SomeDict['SomeKey']
return b

然后像这样运行它:

SomeDict = {}
SomeDict['SomeKey'] = 0
b = UnintentionalValueChangeOfGlobal(10)
print(SomeDict['SomeKey'])

Python 将:1)在函数调用期间查找并使用 SomeDict,即使我忘记将其作为函数的输入提供; 2) 永久更改 SomeDict['SomeKey'] 的值,即使它未包含在函数的返回语句中。

对我来说,这通常会导致变量无意中更改值 - SomeDict['SomeKey'] 在这种情况下,当意图仅操作函数输出时,在调用函数后变为 110 b.

在这种情况下,我更喜欢 python:1) 崩溃,函数内部出现错误,指出 SomeDict 未定义; 2) 在任何情况下,调用函数后都不会永久更改除输出 b 之外的任何变量的值。

我知道不可能在 python 中一起禁用全局变量,但是有一个简单的方法(模块或 IDE 等)可以对我的 python 函数执行静态分析并发出警告当函数使用和/或更改不是函数输出的变量值时?

最佳答案

Python 没有提供任何明显且简单的方法来防止在函数中访问(未声明的)全局名称的原因之一是,在 Python 中,一切(好吧,至少可以分配给名称的一切)都是对象,包括函数、类和模块,因此阻止函数访问未声明的全局名称将导致相当冗长的代码......并且嵌套作用域(闭包等)也无济于事。

当然,尽管全局变量是邪恶的,但有时仍然有合理的理由来改变全局对象。 FWIW,即使是 linter(至少是 pylint 和 pyflakes)似乎也没有任何选项来检测此 AFAICT - 但你必须自己仔细检查,因为我可能忽略了它,或者它可能作为 pylint 存在扩展名或另一个 linter 中。

OTHO,20 多年来我很少遇到此类问题的错误(实际上我不记得发生过一次)。定期应用基本的良好实践 - 尽可能避免副作用的简短函数、有意义的名称和良好的命名约定等、至少对关键部分进行单元测试等 - 似乎足以有效地防止此类问题。

这里的一点是,我有一个关于不可调用全局变量被视为(伪)常量的规则,这通过将它们命名为 ALL_UPPER 来表示。当您实际突变或重新绑定(bind)一个时,这使得它非常变得明显......

作为一个更普遍的规则:Python本质上是一种非常动态的语言(哎呀,你甚至可以在运行时更改对象的类......)并且具有“我们都是同意的成年人”的哲学,所以它是实际上,您会在 Java 等更多“B&D”语言中发现“缺乏”大多数安全防护措施,而是依赖于约定、良好实践和简单的常识。

现在,Python 不仅非常动态,而且还公开了它的大部分内部结构,因此您当然可以(如果它还不存在)编写 pylint extension这至少会检测函数代码中的全局名称(提示:您可以使用 yourfunc.co_code (py2) 或 yourfunc.__code__ (py3) 访问 the compiled code of a function object,然后检查代码中使用了哪些名称)。但是,除非您必须与一群草率、无纪律的开发人员打交道(在这种情况下,您会遇到另一个问题 - 没有技术解决方案来解决愚蠢问题),否则我的拙见是您在浪费时间。

关于python - 识别 python 函数内全局变量的无意读/写?例如使用静态分析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59050026/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com