避免 python 范围错误的策略
Strategies for avoiding python scope errors
我在研究中广泛使用 IPython 笔记本。我发现它们是一个很棒的工具。
然而,不止一次,我被源于变量范围的细微错误所困扰。例如,我将进行一些探索性分析:
foo = 1
bar = 2
foo + bar
而且我认为 foo + bar
是一个对我的目的有用的算法,所以我将它封装在一个函数中,以便更容易应用于更广泛的输入:
def the_function(foo, bar):
return foo + bar
不可避免地,在从头开始构建工作流程后的某处,我会在某处出现拼写错误(例如 def the_function(fooo, bar):
),导致使用全局变量(and/or 已修改) 在函数调用中。这会导致看不见的副作用并导致虚假结果。但是因为它通常是 returns 结果,所以很难找到问题实际发生的位置。
现在,我认识到这种行为是一种特性,我经常故意使用它(为了方便,或出于必要,即函数闭包或装饰器)。但由于我一直 运行 陷入错误,我认为我需要一个更好的策略来避免此类问题(当前策略 = "be careful")。
例如,一种策略可能是始终在局部变量名称前加上“_”。但我很好奇是否没有其他策略 - 甚至 "pythonic" 策略或社区鼓励的策略。
我知道 python 2.x 在范围界定方面与 python 3.x 有所不同 - 我使用 python 3.x.
此外,策略应考虑科学计算的交互性,就像在 IPython Notebook 会场中使用的那样。
想法?
编辑:更具体地说,我正在寻找IPython笔记本策略。
我想把这个问题标记为过于宽泛,但也许以下内容会对您有所帮助。
当您决定将一些有用的代码包装在函数中时,请编写一些测试。如果您认为该代码有用,那么您一定已经将其与一些示例一起使用过。先写测试免得你'forget'.
我个人对库模块的策略是 运行 在 if __name__
== '__main__':
语句中进行测试,无论测试代码在同一个文件还是不同的文件中。我还在编程会话期间多次执行文件 运行 测试,在每个小的更改单元之后(在空闲或类似 IDE 中微不足道)。
使用代码检查程序,它会发现一些拼写错误。 “'fooo' 已设置但从未使用过”。
跟踪你所犯的特定类型的错误,分析它们并考虑个人对策,或者至少学会识别症状。
看看你的例子,当你写一个函数时,不要对全局对象和参数使用相同的名称。在您的示例中,删除或更改全局 'foo' 和 'bar' 或使用其他名称作为参数名称。
我建议你把你的顾虑分开。对于您的探索性分析,请在 iPython 笔记本中编写您的代码,但是当您确定有一些有用的函数时,请打开一个编辑器并将您的函数放入 python 文件中然后你可以导入。
您可以使用 iPython 魔法来自动重新加载您导入的内容。因此,一旦您在 iPython 中测试了它们,您就可以简单地将它们复制到您的模块中。这样,您的功能范围就与您的笔记本隔离开来。另一个优势是,当您准备好在无头环境中进行 运行 操作时,您已经将整个代码库放在一个地方。
最后我自己解决了问题。它建立在目前给出的两个答案的基础上。
您可以在 github 上找到我的解决方案,这是一个单元格魔术扩展:https://github.com/brazilbean/modulemagic
简而言之,此扩展使您能够在笔记本中创建 %% 个模块单元。这些单元格保存为文件并导入回您的会话中。它有效地完成了@shadanan 的建议,但允许您将所有工作保存在同一个地方(方便,并且符合在同一个地方提供代码和结果的 Notebook 哲学)。
因为导入过程对代码进行了沙盒处理,所以它解决了激发我最初提出问题的所有范围阴影错误。它还几乎不涉及使用开销 - 无需重命名变量、打开其他编辑器等。
我在研究中广泛使用 IPython 笔记本。我发现它们是一个很棒的工具。
然而,不止一次,我被源于变量范围的细微错误所困扰。例如,我将进行一些探索性分析:
foo = 1
bar = 2
foo + bar
而且我认为 foo + bar
是一个对我的目的有用的算法,所以我将它封装在一个函数中,以便更容易应用于更广泛的输入:
def the_function(foo, bar):
return foo + bar
不可避免地,在从头开始构建工作流程后的某处,我会在某处出现拼写错误(例如 def the_function(fooo, bar):
),导致使用全局变量(and/or 已修改) 在函数调用中。这会导致看不见的副作用并导致虚假结果。但是因为它通常是 returns 结果,所以很难找到问题实际发生的位置。
现在,我认识到这种行为是一种特性,我经常故意使用它(为了方便,或出于必要,即函数闭包或装饰器)。但由于我一直 运行 陷入错误,我认为我需要一个更好的策略来避免此类问题(当前策略 = "be careful")。
例如,一种策略可能是始终在局部变量名称前加上“_”。但我很好奇是否没有其他策略 - 甚至 "pythonic" 策略或社区鼓励的策略。
我知道 python 2.x 在范围界定方面与 python 3.x 有所不同 - 我使用 python 3.x.
此外,策略应考虑科学计算的交互性,就像在 IPython Notebook 会场中使用的那样。
想法?
编辑:更具体地说,我正在寻找IPython笔记本策略。
我想把这个问题标记为过于宽泛,但也许以下内容会对您有所帮助。
当您决定将一些有用的代码包装在函数中时,请编写一些测试。如果您认为该代码有用,那么您一定已经将其与一些示例一起使用过。先写测试免得你'forget'.
我个人对库模块的策略是 运行 在 if __name__
== '__main__':
语句中进行测试,无论测试代码在同一个文件还是不同的文件中。我还在编程会话期间多次执行文件 运行 测试,在每个小的更改单元之后(在空闲或类似 IDE 中微不足道)。
使用代码检查程序,它会发现一些拼写错误。 “'fooo' 已设置但从未使用过”。
跟踪你所犯的特定类型的错误,分析它们并考虑个人对策,或者至少学会识别症状。
看看你的例子,当你写一个函数时,不要对全局对象和参数使用相同的名称。在您的示例中,删除或更改全局 'foo' 和 'bar' 或使用其他名称作为参数名称。
我建议你把你的顾虑分开。对于您的探索性分析,请在 iPython 笔记本中编写您的代码,但是当您确定有一些有用的函数时,请打开一个编辑器并将您的函数放入 python 文件中然后你可以导入。
您可以使用 iPython 魔法来自动重新加载您导入的内容。因此,一旦您在 iPython 中测试了它们,您就可以简单地将它们复制到您的模块中。这样,您的功能范围就与您的笔记本隔离开来。另一个优势是,当您准备好在无头环境中进行 运行 操作时,您已经将整个代码库放在一个地方。
最后我自己解决了问题。它建立在目前给出的两个答案的基础上。
您可以在 github 上找到我的解决方案,这是一个单元格魔术扩展:https://github.com/brazilbean/modulemagic
简而言之,此扩展使您能够在笔记本中创建 %% 个模块单元。这些单元格保存为文件并导入回您的会话中。它有效地完成了@shadanan 的建议,但允许您将所有工作保存在同一个地方(方便,并且符合在同一个地方提供代码和结果的 Notebook 哲学)。
因为导入过程对代码进行了沙盒处理,所以它解决了激发我最初提出问题的所有范围阴影错误。它还几乎不涉及使用开销 - 无需重命名变量、打开其他编辑器等。