Python language basics 33: variable shadowing and the ‘global’ keyword

Introduction

In the previous post we looked at positional and keyword arguments in a function. We saw how positional arguments were matched up with the arguments in the function signature. We also discussed how keyword arguments could make your code cleaner by explicitly providing the argument names in a function call.

In this post we’ll look at how a variable declared within a function can overshadow another variable declared outside of it.

Variable scope

Variable scope means the bounded location in the code where a variable can be used and has a meaningful value. The most prevalent scope type is local. Locally scoped variables are used within a function. We’ve seen examples of that before:

def get_integer_input(prompt_text):
    user_input = input(prompt_text)
    return int(user_input)

The variables “prompt_text” and “user_input” are both local variables that can be accessed within the get_integer_input method. They cannot be accessed outside this function:

def get_integer_input(prompt_text):
    user_input = input(prompt_text)
    return int(user_input)

print(user_input)

The above code won’t compile as user_input is not defined at that level.

Variables can of course be declared on a higher level called global scope:

user_input = 10

def get_integer_input(prompt_text):
    user_input = input(prompt_text)
    return int(user_input)

print(user_input)

The user_input variable in the first line has global scope and the print statement will print “10”. The local user_input variable within get_integer_input has nothing to do with user_input declared globally just before. To prove this we’ll extend the code slightly:

user_input = 10

def get_integer_input(prompt_text):
    user_input = input(prompt_text)
    print(user_input)
    return int(user_input)

int_input = get_integer_input("Provide a number: ")
print(user_input)

If you run the above code and enter e.g. 40 as the input on line…

user_input = input(prompt_text)

…then the print statements will give 40 and 10. The global user_input variable has been unaffected by the local user_input variable declaration and assignment.

If you use PyCharm then you’ll see a gray squiggly line underneath user_input in the get_integer_input function. If you hover over the variable you’ll see the reason: shadows name ‘user_input’ from outer scope. So user_input in get_integer_input shadows the globally declared user_input variable.

Note that there’s nothing wrong with this in a programmatic sense. The code compiles and runs and it may well have been your intention to introduce a local variable with the same name as that of a global variable. The message in PyCharm is just a safety check: did you really mean to shadow another variable or are you referring to the the global variable? In case you meant to reference the globally declared variable and change its value within the get_integer_input then the “global” keyword comes to the rescue:

user_input = 10

def get_integer_input(prompt_text):
    global user_input
    user_input = input(prompt_text)
    print(user_input)
    return int(user_input)

int_input = get_integer_input("Provide a number: ")
print(user_input)

Running the code with 40 as the user input will also change the value of the globally declared user_input variable to 40. The print statements will print 40 and 40 accordingly.

Read the next part here.

Read all Python-related posts on this blog here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: