Chapter 9: Modules

What's in a __name__?

face Josiah Wang

Remember that libmonster.py is itself a Python script. So you can actually include some code to do things like below.

FACTOR = 5

class Monster:
    def __init__(self, name="Me", food="cookies"):
        self.name = name
        self.food = food


def spawn_monsters():
    return [Monster("Happy", "carrots"), 
            Monster("Bashful", "ice-creams"), 
            Monster("Wild", "cookies")]


def calculate_growthrate(adjustment=3):
    return 25 * FACTOR + adjustment


monster = Monster("Silly", "pizza")
print(f"{monster.name} love {monster.food}!")

When you run the code as a script, i.e. with python3 libmonster.py, it will print "Silly love pizza!"

Now, try running python3 game.py (which import libmonster). It will also print "Silly love pizza!"

However, we do not want to see our test code running when we import libmonster – it is a module for people to use our functions/classes/variables after all.

We only want the test code to run when we explicitly run python3 libmonster.py as a script. Perhaps we just want to test that our class or function works. Can we do that? Of course we can!

What we do is to exploit the fact that Python will set a special variable __name__ as "__main__" only when you run your code as a script (i.e. using python3 libmonster.py). So we can just run our code only if __name__ == "__main__"!

FACTOR = 5

class Monster:
    def __init__(self, name="Me", food="cookies"):
        self.name = name
        self.food = food


def spawn_monsters():
    return [Monster("Happy", "carrots"), 
            Monster("Bashful", "ice-creams"), 
            Monster("Wild", "cookies")]


def calculate_growthrate(adjustment=3):
    return 25 * FACTOR + adjustment


def _test_library():
    monster = Monster("Silly", "pizza")
    print(f"{monster.name} love {monster.food}!")


if __name__ == "__main__":
    _test_library()

Now if you run python3 game.py, it will no longer print out "Silly love pizza!"!

While it is tempting to think of this as a main() method in Java, it is not quite the same since Python does not have or need a main function. So it is better not to think that way!