Каков питонический способ избежать затенения переменных?

У меня часто есть следующий код, который либо приводит к переменной тени, либо к умножению локальных переменных

def whenadult(age):
    return 18 - age

age = 5
needtowait = whenadult(age)

age имеет ту же логическую роль, что и при передаче функции как в главном коде, поэтому я бы хотел избежать создания чего-то вроде l_age in whenadult.

Каков питонический способ решения дилеммы "затенение против переменного умножения"?

ОБНОВЛЕНИЕ: следуя некоторым комментариям, я хочу дать понять, что я искал лучшую практику Python (в отличие от локальной и глобальной переменных)

Ответы

Ответ 1

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

Тот факт, что локальная переменная имеет то же имя, что и переменная, используемая в другом месте в качестве аргумента, особенно не является проблемой. На самом деле, он очень распространен в реальном коде. Например, при выборе случайного модуля stdlib, версии 3.3 для cmd, метод Cmd.onecmd имеет переменную с именем line и передает ее как аргумент методу self.default, который связывает его с параметром, который также называется line,

Тот факт, что переменная, используемая для аргумента, является глобальной переменной, к которой вы могли получить доступ, если у вас не было локальной переменной с тем же именем, не является проблемой, если вы действительно не хотите получить доступ к этой глобальной переменной. Которых вы не хотели в своем существующем коде, и почти никогда не захотите. В этом случае и в большинстве случаев в реальном мире это просто совпадение, которое ничего не значит и ничего не затрагивает, а не проблему, которую вы должны решить.


Проблема, с которой вы сталкиваетесь, заключается в том, что PyCharm не может догадаться, хотите ли вы, чтобы глобальный age был доступен в whenadult. Возможно ли (если не в этом тривиальном случае, может быть, в более сложных случаях), что человек может быть так же смущен, что замедляет его понимание вашего кода? Или что вам когда-нибудь придется писать код в какой-то среде, где ваши рецензенты или преподаватели вашего кода или что-то отклонят ваш код, потому что он не передает какой-либо linter без предупреждений? Может быть.

Но действительно, в любой такой среде они, вероятно, будут жаловаться на то, что вы используете глобальные переменные. И вам действительно не нужно здесь. Единственная причина, по которой age является глобальным, заключается в том, что он должен быть доступен для кода верхнего уровня. Если вы переместите этот код в функцию, age может стать локальным в этой функции. Например:

def whenadult(age):
    return 18 - age

def main():
    age = 5
    needtowait = whenadult(age)

main() # possibly with an if __name__ == '__main__' guard

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

Ответ 2

Всякий раз, когда я получаю предупреждение о переменной shadowing в PyCharm. Я бы попытался переименовать локальную переменную, чтобы использовать префикс подчеркивания как соглашение. Это еще один способ рассмотреть в дополнение к переносу глобальных переменных в функцию main().

    def whenadult(_age):
        return 18 - _age

    age = 5
    needtowait = whenadult(age)