Python Programming

Lecture 8 Decorator, Modules

8.1 Functions (5)


  • Decorator Basics

def shout(word="yes"):
    return word.title()+"!"

# outputs : 'Yes!'

scream = shout

# outputs : 'Yes!'

del shout
# outputs: 'Yes!'

def talk():
    def whisper(word="yes"):
        return word.lower()+"..."
# outputs: 
# "yes..."
# But "whisper" DOES NOT EXIST outside "talk":

def getTalk(kind="shout"):
    def shout(word="yes"):
        return word.title()+"!"
    def whisper(word="yes") :
        return word.lower()+"...";
    if kind == "shout":
        return shout  
        return whisper

talk = getTalk()      
# You can see that "talk" is here a function object:
#outputs : function

#outputs : Yes!

#outputs : yes...
  • decorators are “wrappers”, which means that they let you execute code before and after the function they decorate without modifying the function itself.

# A decorator is a function that expects ANOTHER function as parameter
def my_shiny_new_decorator(a_function_to_decorate):
    def the_wrapper_around_the_original_function():
        print("Before the function runs")


        print("After the function runs")

    return the_wrapper_around_the_original_function

def a_stand_alone_function():
    print("I am a stand alone function, don't you dare modify me")

I am a stand alone function, don't you dare modify me

a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)

Before the function runs
I am a stand alone function, don't you dare modify me
After the function runs

def another_stand_alone_function():
    print("Leave me alone")

Before the function runs
Leave me alone
After the function runs

# @decorator is just a shortcut

def bread(func):
    def wrapper():
    return wrapper

def ingredients(func):
    def wrapper():
    return wrapper

def sandwich(food="--ham--"):

#outputs: --ham--
sandwich = bread(ingredients(sandwich))


@ingredients # The order matters here.
def sandwich(food="--ham--"):


  • Taking decorators to the next level

  • Passing arguments to the decorated function

def a_decorator_passing_arguments(function_to_decorate):
    def a_wrapper_accepting_arguments(arg1, arg2):
        print("I got args! Look: %s, %s" % (arg1, arg2))
        function_to_decorate(arg1, arg2)
    return a_wrapper_accepting_arguments

def print_full_name(first_name, last_name):
    print("My name is %s, %s" % (first_name, last_name))

print_full_name("Peter", "Venkman")
# outputs:
I got args! Look: Peter Venkman
My name is Peter Venkman
  • If you're making general-purpose decorator--one you'll apply to any function or method, no matter its arguments--then just use *args, **kwargs:

def a_decorator_passing_arbitrary_arguments(function_to_decorate):
    # The wrapper accepts any arguments
    def a_wrapper_accepting_arbitrary_arguments(*args, **kwargs):
        print("Do I have args?:")
        function_to_decorate(*args, **kwargs)
    return a_wrapper_accepting_arbitrary_arguments

def function_with_no_argument():
    print("Python is cool, no argument here.")

Do I have args?:
Python is cool, no argument here.

def function_with_arguments(a, b, c):
    print(a, b, c)

Do I have args?:
(1, 2, 3)
1 2 3 

def function_with_named_arguments(a, b, c, platypus="Why not ?"):
    print("Do {0}, {1} and {2} like platypus? {3}".format(a, b, c, platypus))

function_with_named_arguments("Bill", "Linus", "Steve", platypus="Indeed!")
Do I have args ? :
('Bill', 'Linus', 'Steve')
{'platypus': 'Indeed!'}
Do Bill, Linus and Steve like platypus? Indeed! 

8.2 Modules

  • Module is a Python file, followed with .py

  • Storing Your Functions in Modules

def make_pizza(size, *toppings):
    print("\nMaking a " + str(size) +
        "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)
  • It is saved as "" file.

  • We make a separate file called in the same directory as

import pizza

pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
  • Importing Specific Functions

from module_name import function_name

from module_name import function_0, function_1, function_2

from pizza import make_pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
  • Using as to Give a Function an Alias

from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')

from module_name import function_name as fn
  • Using as to Give a Module an Alias

import pizza as p
p.make_pizza(16, 'pepperoni')
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

import module_name as mn
  • Importing All Functions in a Module

from pizza import *
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

from module_name import *
  • The asterisk in the import statement tells Python to copy every function from the module pizza into this program file. Because every function is imported, you can call each function by name without using the dot notation.

  • However, it's best not to use this approach when you're working with larger modules that you didn't write: if the module has a function name that matches an existing name in your project, you can get some unexpected results.

Search for Modules

  • When a module named is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

  • The directory containing the input script (or the current directory when no file is specified).

  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).

  • The installation-dependent default.

import sys


  • Packages are namespaces which contain multiple packages and modules themselves. They are simply directories, but with a twist.

  • Each package in Python is a directory which MUST contain a special file called This file can be empty, and it indicates that the directory it contains is a Python package, so it can be imported the same way a module can be imported.

  • The name of modules are and

  • Be careful! The name of modules you created should not be in conflict with the name of any system module, or any build-in function.

  • Private functions in modules, _xxx, __xxx

def _private_1(name):
    return 'Hello, %s' % name

def _private_2(name):
    return 'Hi, %s' % name

def greeting(name):
    if len(name) > 3:
        return _private_1(name)
        return _private_2(name)
  • You can use those functions, but you would better not use.

Third party modules

import urllib
  • For Python, open the cmd.

  • For Anaconda, open the anaconda prompt.

pip install pillow
  • If you want to use both the Python and Anaconda, there might be some conflicts. Thus, please change file name in the Anaconda. D:\Anaconda\Scripts, pip.exe and pip-script.exe to condapip.exe and condapip-script.exe

pip install you-get #for python
condapip install itchat #for anaconda
conda list


  • Functions
    • Reading: Python for Everybody, Chapter 10.1-10.5, 10.7-10.8
    • Reading: Python Crash Course, Chapter 8
  • Problem Set 2