Acabei de mudar para Pycharm e estou muito feliz com todos os avisos e dicas que ele fornece para melhorar meu código. Exceto por este que eu não entendo:
This inspection detects shadowing names defined in outer scopes.
Sei que é uma má prática acessar variáveis do escopo externo, mas qual é o problema de sombrear o escopo externo?
Aqui está um exemplo, onde Pycharm me dá a mensagem de aviso:
data = [4, 5, 6]
def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
print data
print_data(data)
python
coding-style
pycharm
Framester
fonte
fonte
Respostas:
Não é grande coisa no seu snippet acima, mas imagine uma função com mais alguns argumentos e muito mais linhas de código. Então você decide renomear seu
data
argumento,yadda
mas perde um dos lugares em que é usado no corpo da função ... Agoradata
se refere ao global, e você começa a ter um comportamento estranho - onde você teria muito mais óbvioNameError
se não o fizesse. tem um nome globaldata
.Lembre-se também de que no Python tudo é um objeto (incluindo módulos, classes e funções), portanto não há espaços de nomes distintos para funções, módulos ou classes. Outro cenário é que você importa a função
foo
na parte superior do seu módulo e a utiliza em algum lugar do seu corpo. Então você adiciona um novo argumento à sua função e o denomina - azar -foo
.Por fim, funções e tipos internos também vivem no mesmo espaço para nome e podem ser sombreados da mesma maneira.
Nada disso é muito problemático se você tiver funções curtas, boa nomeação e uma cobertura unittest decente, mas, às vezes, é necessário manter um código menos que perfeito e ser avisado sobre esses possíveis problemas pode ajudar.
fonte
nonlocal
palavra-chave para tornar explícita a referência externa (como nos fechamentos). Observe que isso é diferente de sombreamento, pois explicitamente não oculta variáveis externas.A resposta atualmente mais votada e aceita e a maioria das respostas aqui não atendem .
Não importa quanto tempo sua função seja, ou como você nomeará sua variável descritivamente (para minimizar a chance de uma possível colisão de nomes).
O fato de a variável local da sua função ou seu parâmetro compartilhar um nome no escopo global é completamente irrelevante. E, de fato, não importa com que cuidado você escolha o nome da variável local, sua função nunca poderá prever "se meu nome legal
yadda
também será usado como variável global no futuro?". A solução? Simplesmente não se preocupe com isso! A mentalidade correta é projetar sua função para consumir informações de e somente de seus parâmetros na assinatura , para que você não precise se importar com o que é (ou será) no escopo global e, em seguida, o sombreamento não se torna um problema.Em outras palavras, o problema de sombreamento só importa quando sua função precisa usar o mesmo nome variável local E a variável global. Mas você deve evitar esse design em primeiro lugar. O código do OP realmente não tem esse problema de design. Só que o PyCharm não é inteligente o suficiente e emite um aviso. Portanto, apenas para deixar o PyCharm feliz e também para limpar o nosso código, veja esta solução citando a resposta de silyevsk para remover completamente a variável global.
Esta é a maneira correta de "resolver" esse problema, corrigindo / removendo sua coisa global, não ajustando sua função local atual.
fonte
print_data
É uma variável global. Pense nisso ...Uma boa solução alternativa em alguns casos pode ser mover o código vars + para outra função:
fonte
Depende de quanto tempo a função é. Quanto maior a função, maior a chance de que alguém a modifique no futuro escreva
data
pensando que isso significa global. Na verdade, significa local, mas como a função é longa, não é óbvio para eles que existe um local com esse nome.Para sua função de exemplo, acho que sombrear o global não é nada ruim.
fonte
Faça isso:
fonte
fonte
data
, tudo dentro de algumas centenas de linhas de código?data
é um nome local nessa função, então nem me incomodo em verificar / lembrar se existe um global com o mesmo nome , sem falar no que ele contém.False
- se você não definir, mas apenas tentar usodata
, parece-se através de escopos até encontrar um, por isso faz encontrar o mundialdata
.data = [1, 2, 3]; def foo(): print(data); foo()
Eu gosto de ver uma marca verde no canto superior direito em pycharm. Anexo os nomes das variáveis com um sublinhado apenas para limpar este aviso, para que eu possa me concentrar nos avisos importantes.
fonte
Parece 100% padrão de código pytest
Vejo:
https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
Eu tive o mesmo problema com, é por isso que encontrei este post;)
E avisará com
This inspection detects shadowing names defined in outer scopes.
Para corrigir isso, apenas mova seu
twitter
dispositivo para./tests/conftest.py
E remova o
twitter
aparelho como em./tests/test_twitter2.py
Isso fará com que o controle de qualidade seja feliz, Pycharm e todos
fonte