PyCharm 是一款由 JetBrains 开发的受欢迎的 Python 集成开发环境(IDE)。作为一款现代化的 IDE,PyCharm 几乎支持所有你能想到的功能,例如代码调试、语法高亮、项目管理、智能提示、自动补全、单元测试以及版本控制等。除此之外,PyCharm 还提供 Django 的高级 Web 开发工具,并且支持 Anaconda 和 IronPython 进行数据科学开发。

然而,在使用 PyCharm 工作时,你可能会遇到一些警告信息,其中部分不是 Python 本身的错误信息。“Shadows name from outer scope”就是其中最常见的警告信息之一,这会给新用户带来一定的困扰。本文将解释为什么会出现该警告,以及你可以采取什么措施来避免出现该警告。

为什么会出现Shadows name from outer scope”警告

让我们看下面的代码片段作为示例:

1
2
3
4
5
6
access_token = "HCbhQHCuG05WdVm506BE"

def list_tag(access_token): # Warning: Shadows name 'access_token' from outer scope
print(access_token)

list_tag(access_token)

可以明显看出,在第一行我们在全局作用域中定义了 access_token,而在 list_tag 函数中我们重复使用了该名字。在 PyCharm 中,在函数内部和外部重复使用同一名字被称为“Shadows name”,因此会导致“Shadows name ‘access_token’ from outer scope”的警告。这只是一条警告,不会影响代码的运行。

尽管这个示例没什么问题,运行也没问题,但如果你继续忽略该警告信息,它可能导致未来出现奇怪的行为。

假设 list_tag 函数的参数不再是单个参数,而是多个参数,其内部逻辑也变得更加复杂。你决定手动将 access_token 重命名为 token,但在某些地方遗漏了修改。

如果你再次运行这段代码,它可能看起来运行正常,但最终结果肯定会很奇怪。这是因为现在 access_token 指的是全局对象,token 指的是局部对象,两者是不同的,但在函数中你把它们来回混用。

如何规避“Shadows name from outer scope”警告

现在我们明白了该警告背后的原因,解决方案其实很简单:你需要避免在代码中重复使用相同的名字。

这样做不仅可以减少代码中出现奇怪行为的可能性,而且可以使调试变得更加简单,因为如果 Python 无法找到全局名称或局部名称,会直接抛出 NameError 错误。

还有一点要记住,你不应该使用隐射的方式来“隐射”模块、类和函数。

更新后的示例代码如下::

1
2
3
4
5
6
access_token = "HCbhQHCuG05WdVm506BE"  

def list_tag(token):
print(token)

list_tag(access_token)

或者你可以像下面这样将全局变量移入另一个函数中:

1
2
3
4
5
6
7
8
9
10
def list_tag(access_token):
print(access_token)

def main():
access_token = "HCbhQHCuG05WdVm506BE"
list_tag(access_token)


if __name__ == '__main__':
main()

注意,如果代码的结构如下:

1
2
3
4
5
6
def list_tag(access_token): # Warning: Shadows name 'access_token' from outer scope
print(access_token)

if __name__ == '__main__':
access_token = "HCbhQHCuG05WdVm506BE"
list_tag(access_token)

仍会出现“Shadows name ‘access_token’ from outer scope”的警告。

这是因为在 if 条件内,access_token 是被定义为全局变量,if __name__ == '__main__': 是一个 Python 惯用法,用于判断一个模块是否作为脚本直接执行,并不是一个函数。

(END)