Skip to content
Foxipa
Code Completion 6 Challenges

Complete the Python decorators code

Practice applying function and class decorators, forwarding wrapper calls, preserving function metadata, configuring factories, and composing decorators.

Intermediate ~10 min read

Challenge 1

Apply add_greeting to greet using decorator syntax.

python Your answer
def add_greeting(func):
    def wrapper(name):
        return "Hello, " + func(name)
    return wrapper


def greet(name):
    return name

print(greet("Ada"))

Press Ctrl⌘Enter to check your answer

Challenge 2

Write the wrapper parameters so it can accept and forward any positional and keyword arguments.

python Your answer
def traced(func):
    def wrapper():
        print("calling")
        result = func(*args, **kwargs)
        return result
    return wrapper

Press Ctrl⌘Enter to check your answer

Challenge 3

Make prefix return a decorator that adds label before the function result.

python Your answer
def prefix(label):
    def decorate(func):
        def wrapper(name):
            return 
        return wrapper
    return decorate

Press Ctrl⌘Enter to check your answer

Challenge 4

Add the outer decorator so message uses both decorators.

python Your answer
def add_exclamation(func):
    def wrapper(text):
        return func(text) + "!"
    return wrapper

def add_brackets(func):
    def wrapper(text):
        return "[" + func(text) + "]"
    return wrapper


def message(text):
    return text

print(message("hello"))

Press Ctrl⌘Enter to check your answer

Challenge 5

Use functools.wraps so the decorated function keeps the original function metadata.

python Your answer
from functools import wraps

def trace(func):
    
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@trace
def get_label(value):
    """Return the supplied label."""
    return value

print(get_label.__name__)
print(get_label.__doc__)
print(get_label.__wrapped__("ready"))

Press Ctrl⌘Enter to check your answer

Challenge 6

Finish the class decorator so the new describe method becomes available on PdfExporter instances and the class name stays bound to the class.

python Your answer
def add_description(cls):
    def describe(self):
        return f"{type(self).__name__} uses {self.extension}"
    cls.describe = describe
    

@add_description
class PdfExporter:
    extension = ".pdf"

print(PdfExporter().describe())

Press Ctrl⌘Enter to check your answer