Вопрос или проблема
У меня есть этот код в PyCharm:
device_name=""
current_device=""
if torch.cuda.is_available():
current_device = torch.cuda.current_device()
device_name = torch.cuda.get_device_name(current_device)
file_footer += str(current_device) + ', ' + device_name +', modell: ' + used_model + ', ' + used_language
Как вы можете видеть, я объявляю две переменные вне блока if. Затем я присваиваю обоим переменным значения внутри блока if. Наконец, я использую их вне блока if.
PyCharm выдает мне одно предупреждение для этого фрагмента "Shadows name 'current_device' from outer scope"
, хотя device_name
используется абсолютно логичным образом.
Сначала я думал, что это несовпадение типов, я инициализирую current_device
с пустой строкой
, но позже присваиваю ей int
. Поэтому я попробовал оба этих обходных пути:
current_device = 0
current_device = None
но это не помогло. Я даже пытался спровоцировать предупреждение для device_name (которому присваивается строка
), инициализировав его int
:
device_name = 0
но это было совершенно приемлемо!?!?
Я искал в своем коде эти имена переменных, и приведенный фрагмент – единственное место, где я их использую. Я прочитал этот вопрос (и некоторые другие), но не думаю, что ответы там (кроме отключения этого предупреждения) применимы к моей ситуации.
Почему я получаю это предупреждение для current_device
??
.
Ответ или решение
В вашей кодовой базе, как вы верно отметили, существует предупреждение от PyCharm о том, что переменная current_device
затеняет переменную экспортированную из внешнего контекста. Попробуем глубже понять, почему возникает это предупреждение и почему оно относится только к одной переменной, несмотря на наличие двух переменных, которые вы инициализируете в одном месте.
Объяснение предупреждения "Shadows name from outer scope"
-
Определение затенения (Shadowing):
Затенение происходит, когда вы объявляете переменную с тем же именем в более узкой области видимости, чем она уже существует. В вашем коде переменнаяcurrent_device
определяется внеif
-блока и затем переопределяется внутри него. Это приводит к затенению, так как при обращении к переменнойcurrent_device
в коде внутри блокаif
, интерпретатор будет использовать локальную версию переменной, а не ту, что была определена ранее. -
Структура кода:
В вашей ситуации вы определяете переменныеdevice_name
иcurrent_device
внеif
-блока. Затем, если условиеtorch.cuda.is_available()
выполняется, вы назначаете значения этим переменным. Однако, толькоcurrent_device
признаётся как затеняющая, поскольку PyCharm распознает, что это имя переменной связано с объектом (число), в то время какdevice_name
остаётся строковым типом. -
Причина отсутствия предупреждения для
device_name
:
Переменнаяdevice_name
, будучи строковой, не создаёт в контекстеif
-блока конфликтов с типами данных. Локальная декларация вif
-блоке служит просто для назначения нового значения, и не вызывает затенения, как в случае сcurrent_device
. PyCharm не распознает это как потенциальную проблему, так как строка не пересекается с другими значениями. В результате, предупреждение о затенении выдаётся только для переменнойcurrent_device
. -
Решения:
- Переименование переменной: Если вы хотите избавиться от этого предупреждения, вы можете просто переименовать вашу переменную
current_device
внутриif
-блока, чтобы избежать затенения. - Изменение области видимости: Рассмотрите возможность использования более строгих архитектурных принципов, таких как обёртка кода в функции. Это может помочь избежать подобных предупреждений.
- Игнорирование предупреждений: Если предпосылки к вашему коду корректны и не влияют на логику, вы можете игнорировать это предупреждение или отключить его в настройках PyCharm.
- Переименование переменной: Если вы хотите избавиться от этого предупреждения, вы можете просто переименовать вашу переменную
Заключение
Проблема предупреждения о затенении в вашем коде касается более глубоких понятий о локальных и глобальных переменных, а также правил типизации в Python. Важно помнить, что каждое предупреждение в IDE, подобно PyCharm, служит напоминанием удостовериться, что ваш код остаётся чистым, понятным и поддерживаемым. Понимание и устранение таких предупреждений не только улучшает качество кода, но и способствует вашим навыкам программирования в долгосрочной перспективе.