![]() |
活泼的伤疤 · window.focus() 怎么使用 - ...· 8 月前 · |
![]() |
想表白的沙滩裤 · php 正则替换实现伪静态-掘金· 1 年前 · |
![]() |
爽快的手电筒 · 「android布局背景颜色的代码」相关问答 ...· 1 年前 · |
![]() |
独立的柚子 · Get Started with ...· 1 年前 · |
我刚转到PyCharm,我很高兴看到它为我提供了改进代码的所有警告和提示。除了这个我不明白的:
此检查检测外部作用域中定义的隐藏名称。
我知道从外部范围访问变量是不好的做法,但是隐藏外部范围有什么问题呢?
下面是一个例子,其中PyCharm给出了警告消息:
data = [4, 5, 6]
def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
print data
print_data(data)
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)
这取决于函数的长度。函数越长,将来修改它的人就越有可能编写
data
,认为它意味着全局。实际上,它的意思是本地,但是因为函数太长,所以对他们来说并不明显,存在一个具有该名称的本地。
对于您的示例函数,我认为隐藏全局一点也不坏。
上面的代码片段没有什么大不了的,但是想象一个函数有更多的参数和更多的代码行。然后,您决定将
data
参数重命名为
yadda
,但忽略了它在函数体中使用的一个位置.现在
data
指的是全局,而你开始有奇怪的行为--如果你没有全局名称
data
,你会有一个更明显的
NameError
。
还请记住,在Python中,所有东西都是一个对象(包括模块、类和函数),因此函数、模块或类没有不同的名称空间。另一个场景是在模块顶部导入函数
foo
,并在函数体的某个位置使用它。然后向函数中添加一个新参数,并将其命名为“厄运-
foo
”。
最后,内置函数和类型也存在于相同的命名空间中,并且可以以相同的方式隐藏。
如果功能短、命名良好和单元测试复盖范围良好,那么这都不是什么大问题,但是,有时候您必须维护不太完美的代码,并且警告您这些可能的问题可能会有帮助。
在某些情况下,一个很好的解决方法可能是将变量和代码移动到另一个函数中:
def print_data(data):
print data
def main():
data = [4, 5, 6]
print_data(data)
main()
目前投票最多并被接受的答案 和这里的大多数答案都忽略了重点。
不管您的函数是多长时间,或者您如何将变量命名为描述符(希望最大限度地减少潜在名称冲突的可能性)。
函数的局部变量或其参数碰巧在全局范围内共享名称这一事实是完全不相关的。事实上,无论您多么谨慎地选择局部变量名称,您的函数都无法预见“我的酷名
yadda
将来是否也会被用作全局变量?”解决方案是什么?不要担心这一点!
正确的思维方式是设计您的函数来使用输入,并且只使用它在签名
中的参数。这样,您就不需要关心(或将要)在全局范围内是什么,然后隐藏就完全不是问题了。
换句话说,只有当函数需要使用同名局部变量和全局变量时,隐藏问题才重要。但首先你应该避免这样的设计。OP的代码实际上没有这样的设计问题。只是PyCharm不够聪明,它会发出警告以防万一。因此,为了使PyCharm高兴,同时也使我们的代码整洁,可以看到这个解决方案引用了 西莱夫斯克的回答 来完全删除全局变量。
def print_data(data):
print data
def main():
data = [4, 5, 6]
print_data(data)
main()
这是“解决”这个问题的正确方法,方法是修复/删除全局事物,而不是调整当前的本地函数。
这样做:
data = [4, 5, 6]
def print_data():
global data
print(data)
print_data()
它看起来像是100%的 吡喃 代码模式。
请参见:
https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
我也有同样的问题,这就是我找到这篇文章的原因;)
# ./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
它将使用
This inspection detects shadowing names defined in outer scopes.
发出警告
要解决这个问题,只需将
twitter
夹具移动到
./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
夹具,如
./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)
![]() |
想表白的沙滩裤 · php 正则替换实现伪静态-掘金 1 年前 |