top of page

Accessing Global Variables The Proper Way in Python

Introduction


Global variables are accessible to any part of a program--or so we thought.

This guide will break down exactly how global variables are used... and whether they should be used altogether.


Printing


Let's test out a global variable, score:

score = 0


def main():
	print(score)


if __name__ == "__main__":
	main()

So far, so good--the output is zero.

score = 0
score += 1

def main():
	print(score)


if __name__ == "__main__":
	main()

Even upon modifying the value of score, we still get the expected 1. So what's wrong?


Modifying Through Functions


The devil lies in attempting to modify a global variable within a function.

score = 0


def increment():
	score += 1


def decrement():
	score -= 1


def main():
	increment()
	decrement()
	print(score)


if __name__ == "__main__":
	main()

Within both decrement( ) and increment( ), score is treated as a local variable, rather than global.


Here, Python raises an 'UnboundLocalError.'


There is a quick fix to this problem, however:

score = 0


def increment():
	global score
	score += 1


def decrement():
	global score
	score -= 1


def main():
	increment()
	decrement()
	print(score)


if __name__ == "__main__":
	main()

Simply specify that score is a global variable beforehand and you're good to go! But could we still improve upon this program...


Classes and Objects


Instead of having to deal with the hassle of specifying global variables (which can become tedious when many arise), we can simply use object-oriented programming to replace global variables with instance variables.

class Game():
	def __init__(self):
		self._score = 0
	
	@property
	def score():
		return self._score

	def increment(self):
		self._score += 1

	def decrement(self):
		self._score -= 1


def main():
	game1 = Game()
	print(game1.score)
	game1.increment()
	print(game1.score)
	game1.decrement()
	print(game1.score)


if __name__ == "__main__":
	main()

Turning those increment and decrement functions into instance methods and treating score as an instance variable helps us omit having to use global variables altogether. Much more efficient.


As a side note, if you're interested:

  • by convention, the _score instance variable has an underscore by convention, to specify that it's meant only to be accessed within a method and kept private. We could have very well just called it "score" too!

  • @property decorator allows us to call the score method without using the ( ) like usual methods do


Final Thoughts


Hopefully now you'll consider using classes instead of global variables in your next excursion in Python.


Thanks for reading!

Commenti


bottom of page