What is the pythonic way to avoid shadowing variables?

Question:

I often have the following code which either leads to variable shadowing or to a multiplication of local variables

def whenadult(age):
    return 18 - age

age = 5
needtowait = whenadult(age)

age has the same logical role both when passed to the function as in the main code so I would like to avoid creating something like l_age in whenadult.

What is the pythonic way to solve the “shadowing vs. variable multiplication” dilemma?

UPDATE: following up on some comments I want to make it clear that I was looking for a Python best practice (as opposed to local vs. global variables scope)

Asked By: WoJ

||

Answers:

The fact that the local variable (and function parameter) age happens to have the same name as a variable somewhere else in your program is irrelevant. The whole point of local variables is that they only live within the local scope of the function they’re defined in.

The fact that the local variable has the same name as the variable used elsewhere as an argument is especially not a problem. In fact, it’s very common in real-life code. For example, picking a random stdlib module, the 3.3 version of cmd, the Cmd.onecmd method has a variable named line, and it passes it as an argument to the self.default method, which binds it to a parameter that’s also named line.

The fact that the variable used for the argument happens to be a global variable that you could have accessed, if you didn’t have a local variable of the same name, is not a problem unless you actually wanted to access that global variable. Which you didn’t want to in your existing code, and almost never should want to. In this case, and in most real-world cases, it’s simply a coincidence that means nothing and affects nothing, not a problem you have to solve.


The problem you’re having is that PyCharm can’t guess whether you wanted the global age to be accessible in whenadult. Is it possible (if not in this trivial case, maybe in more complex cases) that a human might be similarly confused, slowing down his comprehension of your code? Or that you’ll one day have to write code in some environment where your code reviewers or teacher or whatever will reject your code because it doesn’t pass some linter with no warnings? Maybe.

But really, in any such environment, they’d probably complain about you using global variables in the first place. And you really don’t need to here. The only reason age is a global is that it has to be accessible to the top-level code. If you move that code into a function, age can become a local in that function. For example:

def whenadult(age):
    return 18 - age

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

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

This will make PyCharm happy, and any linter tools, and any easily-confused or rigidly-minded human readers. It’ll even make your code a tiny bit faster. On the other hand, it’s more code to read—only three lines and one indent, but then the whole program is only eight lines long. So, it’s a tradeoff that you can make on a case-by-case basis.

Answered By: abarnert

Whenever I got the warning of shadowing variable in PyCharm. I would try to rename the local variable to use the underscore prefix as the convention. That’s another way to consider in addition to wrap global variables into a main() function.

    def whenadult(_age):
        return 18 - _age

    age = 5
    needtowait = whenadult(age)
Answered By: Devy

PyCharm is going out of its way to prevent you from accidentally accessing(usually due to typos) a variable from the outer scope because doing so can create really nasty bugs.

Short Answer:
Most executables don’t need to access the global state, so follow this structure that makes main a python function:

def helper_function():
  # a function that will be used by main()
.
.
.
def main():
  # make MAIN a function.
  helper_function() 

if __name__ == '__main__':
  main() 
  # DONT define any variables here in this GLOBAL scope
Answered By: Harsh Verma
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.