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

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

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

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

data = [4, 5, 6]

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

print_data(data)

当前回答

它看起来像是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和每个人都感到高兴。

其他回答

这样做:

data = [4, 5, 6]

def print_data():
    global data
    print(data)

print_data()

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

# noinspection PyShadowingNames

我喜欢在PyCharm的右上角看到一个绿色的勾。我在变量名后面加上下划线,只是为了清除这个警告,这样我就可以专注于重要的警告。

data = [4, 5, 6]

def print_data(data_):
    print(data_)

print_data(data)

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

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

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

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

data = [4, 5, 6] # Your global variable

def print_data(data): # <-- Pass in a parameter called "data"
    print data  # <-- Note: You can access global variable inside your function, BUT for now, which is which? the parameter or the global variable? Confused, huh?

print_data(data)