Я только что переключился на Pycharm, и я очень рад всем предупреждениям и подсказкам, которые он дает мне для улучшения моего кода. За исключением этого, которое я не понимаю:
This inspection detects shadowing names defined in outer scopes.
Я знаю, что это плохая практика для доступа к переменной из внешней области, но в чем проблема с затенением внешней области?
Вот один пример, где Pycharm дает мне предупреждающее сообщение:
data = [4, 5, 6]
def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
print data
print_data(data)
python
coding-style
pycharm
Framester
источник
источник
Ответы:
В приведенном выше фрагменте нет ничего сложного, но представьте себе функцию с несколькими аргументами и несколькими строками кода. Затем вы решаете переименовать свой
data
аргумент,yadda
но пропустите одно из мест, где он используется в теле функции ... Теперьdata
относится к глобальному, и вы начинаете странно себя вести - где у вас было бы гораздо более очевидное,NameError
если бы вы этого не сделали иметь глобальное имяdata
.Также помните, что в Python все является объектом (включая модули, классы и функции), поэтому нет отдельных пространств имен для функций, модулей или классов. Другой сценарий заключается в том, что вы импортируете функцию
foo
в верхней части вашего модуля и используете ее где-то в теле функции. Затем вы добавляете новый аргумент в вашу функцию и называете его - невезение -foo
.Наконец, встроенные функции и типы также находятся в одном и том же пространстве имен и могут быть затенены одинаково.
Ничего из этого не представляет большой проблемы, если у вас короткие функции, хорошее наименование и приличное покрытие юнит-тестами, но иногда вам приходится поддерживать не совсем идеальный код, и может помочь предупреждение о таких возможных проблемах.
источник
nonlocal
ключевое слово, чтобы сделать ссылку на внешнюю оценку (как в замыканиях) явной. Обратите внимание, что это отличается от теневого копирования, поскольку явно не скрывает переменные извне.В настоящее время наиболее одобренный и принятый ответ и большинство ответов здесь пропускают суть.
Неважно, какова длина вашей функции или как вы называете переменную описательно (чтобы минимизировать вероятность потенциального конфликта имен).
Тот факт, что локальная переменная вашей функции или ее параметр совместно используют имя в глобальной области видимости, совершенно не имеет значения. И на самом деле, как бы тщательно вы ни выбирали имя локальной переменной, ваша функция никогда не сможет предвидеть «будет ли мое классное имя
yadda
также использоваться в качестве глобальной переменной в будущем?». Решение? Просто не беспокойся об этом! Правильное мышление заключается в том, чтобы спроектировать вашу функцию так, чтобы она использовала входные данные и только из ее параметров в сигнатуре , таким образом вам не нужно заботиться о том, что находится (или будет) в глобальной области видимости, и тогда затенение вообще не будет проблемой.Другими словами, проблема теневого копирования имеет значение только тогда, когда вашей функции необходимо использовать локальную переменную с тем же именем И глобальную переменную. Но вы должны избегать такого дизайна в первую очередь. Код OP на самом деле не имеет такой проблемы дизайна. Просто PyCharm недостаточно умен и выдает предупреждение на всякий случай. Итак, просто чтобы порадовать PyCharm, а также сделать наш код чистым, посмотрите, как это решение цитирует ответ Сильевска на полное удаление глобальной переменной.
Это правильный способ «решить» эту проблему, исправляя / удаляя вашу глобальную вещь, а не настраивая текущую локальную функцию.
источник
print_data
IS является глобальной переменной. Подумайте об этом ...В некоторых случаях хорошим решением может быть перемещение кода vars + в другую функцию:
источник
Это зависит от того, как долго эта функция. Чем дольше функция, тем больше шансов, что кто-то ее модифицирует в будущем и напишет,
data
думая, что она означает глобальную. Фактически это означает локальный, но поскольку функция настолько длинная, для них не очевидно, что существует локальный объект с таким именем.Для вашего примера функции, я думаю, что слежка за глобальным совсем не плохо.
источник
Сделай это:
источник
источник
data
, все в глубине нескольких сотен строк кода?data
это локальное имя этой функции, так что я даже не потрудился проверить / вспомнить ли глобальная то же имя существует , не говоря уже , что она содержит.False
- если вы не определяете, а просто пытаетесь использоватьdata
, он просматривает области видимости, пока не найдет его, поэтому это действительно найти глобальнуюdata
.data = [1, 2, 3]; def foo(): print(data); foo()
Мне нравится видеть зеленую галочку в правом верхнем углу в pycharm. Я добавляю имена переменных с подчеркиванием, чтобы очистить это предупреждение, чтобы сосредоточиться на важных предупреждениях.
источник
Похоже, это 100% шаблон кода Pytest
видеть:
https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
У меня была такая же проблема, вот почему я нашел этот пост;)
И это будет предупреждать с
This inspection detects shadowing names defined in outer scopes.
Чтобы это исправить, просто переместите
twitter
прибор в./tests/conftest.py
И удалить
twitter
приспособление как в./tests/test_twitter2.py
Это будет радовать QA, Pycharm и всех остальных
источник