我刚刚切换到PyCharm,我很高兴它为我提供的所有警告和提示来改进我的代码。除了这个我不明白

此检查检测在外部作用域中定义的阴影名称。

我知道从外部范围访问变量是不好的做法,但阴影外部范围的问题是什么?

下面是一个例子,PyCharm给了我警告信息:

data = [4, 5, 6]

def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
    print data

print_data(data)

当前回答

这取决于函数的长度。函数越长,将来修改它的人写数据时认为它意味着全局的可能性就越大。实际上,它指的是局部函数,但由于函数太长,它们并不清楚是否存在具有该名称的局部函数。

对于你的例子函数,我认为遮蔽全局一点都不坏。

其他回答

在上面的代码片段中没有什么大问题,但是想象一下,一个函数有更多的参数和相当多的代码行。然后,您决定将数据参数重命名为yadda,但忽略了它在函数体中使用的一个地方……现在data引用全局数据,你开始有奇怪的行为——如果你没有全局名称数据,你会有一个更明显的NameError。

还要记住,在Python中一切都是对象(包括模块、类和函数),因此函数、模块或类没有不同的命名空间。另一种情况是在模块的顶部导入函数foo,并在函数体的某处使用它。然后在函数中添加一个新参数,并将其命名为- bad luck - foo。

最后,内置函数和类型也位于相同的名称空间中,可以以相同的方式隐藏。

如果你有简短的函数,良好的命名和良好的单元测试覆盖率,这些都不是什么大问题,但是,有时候你必须维护不太完美的代码,对这些可能的问题发出警告可能会有所帮助。

我认为这条规则没有多大帮助。我只是禁用了它,点击设置->编辑器->检查,然后勾选这条规则:

Shadowing names from outer scope

这取决于函数的长度。函数越长,将来修改它的人写数据时认为它意味着全局的可能性就越大。实际上,它指的是局部函数,但由于函数太长,它们并不清楚是否存在具有该名称的局部函数。

对于你的例子函数,我认为遮蔽全局一点都不坏。

它看起来像是100%的pytest代码模式。

See:

Pytest fixture:显式的、模块化的、可伸缩的

我也有同样的问题,这就是为什么我找到了这篇文章;)

# ./tests/test_twitter1.py
import os
import pytest

from mylib import db
# ...

@pytest.fixture
def twitter():
    twitter_ = db.Twitter()
    twitter_._debug = True
    return twitter_

@pytest.mark.parametrize("query,expected", [
    ("BANCO PROVINCIAL", 8),
    ("name", 6),
    ("castlabs", 42),
])
def test_search(twitter: db.Twitter, query: str, expected: int):

    for query in queries:
        res = twitter.search(query)
        print(res)
        assert res

并且它将警告“此检查检测在外部作用域中定义的阴影名称”。

要解决这个问题,只需将twitter fixture移动到。/tests/conftest.py

# ./tests/conftest.py
import pytest

from syntropy import db


@pytest.fixture
def twitter():
    twitter_ = db.Twitter()
    twitter_._debug = True
    return twitter_

并删除twitter fixture,如./tests/test_twitter2.py:

# ./tests/test_twitter2.py
import os
import pytest

from mylib import db
# ...

@pytest.mark.parametrize("query,expected", [
    ("BANCO PROVINCIAL", 8),
    ("name", 6),
    ("castlabs", 42),
])
def test_search(twitter: db.Twitter, query: str, expected: int):

    for query in queries:
        res = twitter.search(query)
        print(res)
        assert res

这将使QA, PyCharm和每个人都感到高兴。

要忽略这个警告,就像克里斯托弗在评论中说的,你可以在上面评论

# noinspection PyShadowingNames