Имя теней xyz из внешней области

Я использую pycharm и перечисляет все ошибки/предупреждения, связанные с кодом. Хотя я понимаю большинство из них, я не уверен в этом "Shadows name xyz from the external scope". Есть несколько сообщений SO по этому поводу: Насколько плохо скрываются имена, определенные во внешних областях?, но затем они, похоже, обращаются к глобальной переменной.

В моем случае моя функция __main__ имеет несколько имен переменных, а затем вызывает другую функцию sample_func, которая снова использует эти имена переменных (в первую очередь имена переменных цикла). Я предполагаю, что у меня есть другая функция, область для этих переменных будет локальной, однако предупреждение, похоже, предполагает иное.

Любые мысли? Для справки здесь приведен код:

def sample_func():
    for x in range(1, 5):  --> shadows name x from outer scope
        print x

if __name__ == "__main__":
    for x in range(1, 5):
        sample_func()

Ответ 1

Предупреждение о потенциальной опасности, которую вы вводите, путем повторного использования этих имен во внутренних областях. Это может привести к пропуску ошибки. Например, рассмотрим этот

def sample_func(*args):
    smaple = sum(args) # note the misspelling of `sample here`
    print(sample * sample)

if __name__ == "__main__":
    for sample in range(1, 5):
        sample_func()

Поскольку вы использовали одно и то же имя, ваша орфографическая ошибка внутри функции не вызывает ошибки.

Когда ваш код очень прост, вы избавитесь от этого типа вещей без каких-либо последствий. Но хорошо использовать эти "лучшие практики", чтобы избежать ошибок при более сложном коде.

Ответ 2

Код внутри вашей ветки if вашей основной функции фактически находится в области видимости, когда вы находитесь внутри sample_func. Вы можете прочитать переменную x (попробуйте ее). Это нормально, так как вам все равно, так что у вас есть несколько вариантов для продвижения вперед.

1) Отключите предупреждения теневого копирования в pycharm. Честно говоря, это самое прямолинейное и в зависимости от того, насколько опытным из вас является кодер, возможно, он имеет наибольший смысл (если вы относительно новичок, я бы этого не сделал).

2) Поместите основной код в основную функцию. Это, вероятно, лучшее решение для любого кода уровня производства. Python очень хорош в том, чтобы делать то, что вы хотите сделать, поэтому будьте осторожны, чтобы не попасть в ловушки. Если вы строите модуль, наличие логики на уровне модуля может привести вас к липким ситуациям. Вместо этого может быть полезно следующее:

def main():
    # Note, as of python 2.7 the interpreter became smart enough
    # to realize that x is defined in a loop, so printing x on this
    # line (prior to the for loop executing) will throw an exception!
    # However, if you print x by itself without the for loop it will
    # expose that it still in scope. See https://gist.github.com/nedrocks/fe42a4c3b5d05f1cb61e18c4dabe1e7a
    for x in range(1, 5):
        sample_func()

if __name__ == '__main__':
    main()

3) Не используйте те же имена переменных, которые вы используете в более широких областях. Это довольно сложно обеспечить и выглядит противоположно # 1.

Ответ 3

Это просто предупреждение, как объясняется в связанном вопросе, когда возникают проблемы, но в вашем случае x является локальным для вашей функции. Вы получаете предупреждение из-за того, что x внутри вашего if __name__ == "__main__": находится в глобальном масштабе. Это не повлияет на x в вашей функции, поэтому я не буду беспокоиться о предупреждении.

Ответ 4

Я знаю, что это старый поток, и это не подходит для проблемы, о которой спрашивал айзер, но я искал ответ на вопрос, почему PyCharm показывал мне сообщение "Shadows name from the external scope" на комплексном блоке оператора iffif...

Оказывается, что я запустил некоторые глобальные имена переменных в начале функции, но использовал более строчный код в блоке if if elif в дальнейшем.

Ошибка школьного мальчика, которую я знаю, но как только я исправил это, сообщение "Shadows name from the external scope" в PyCharm исчезло, а переменные перестали отображаться как серые...

Итак, урок, который я узнал, заключается в том, что это сообщение PyCharm может быть вызвано чем-то простым, как ошибка верхнего/нижнего регистра в имени переменной...

Я только осознал проблему, пока я разбивал функцию на три функции, чтобы увидеть, удалит ли это ошибку "Тени...", поскольку я думал, что у меня проблема с отступом, и это вызывало проблему!

Это может помочь другому новичку, который царапает голову, задаваясь вопросом, почему они получают эту ошибку: -)

Ответ 5

Я сталкивался с этим предупреждением для аргумента в методе с именем year, но никакая другая переменная не разделяла это имя. Затем я понял, что это из-за строки from pyspark.sql.functions import *, которая импортировала переменную year. Изменив это, чтобы импортировать только нужные нам функции, избавьтесь от предупреждения.