Python Guide Sidebar

Function Annotations: Exploring Data Description in Python

Python function annotations help you describe the data your function uses. You can specify the types of input and output for better understanding and error prevention. This feature, introduced in PEP 3107, improves readability without affecting how your code runs

Function annotations in Python provide a way to attach metadata to function parameters and return values. They help in enhancing code readability and support better documentation. Annotations are not enforced and are just informative.

Let’s explore what function annotations are, how to use them, and build a simple mini-project to put your knowledge into practice.

What Are Python Function Annotations?

Function annotations let you add extra information to your functions. This information can describe the data types of the function’s inputs and outputs.

Key Features:

  • They don’t enforce any rules; they are only hints.
  • Annotations make your code more readable.
  • Tools like MyPy can use them to catch errors.

Example:

def greet(name: str) -> str:
    return f"Hello, {name}!"

  • name: str means the function takes a string as input.
  • -> str shows the function returns a string.

Why Use Function Annotations?

  1. Clarity: Makes your code easier to understand.
  2. Documentation: Acts as built-in notes for your functions.
  3. Error Checking: Tools can catch mistakes before you run the code.
  4. Team Collaboration: Helps others understand your code better.

How to Use Function Annotations

The syntax is simple:

  1. Add a colon (:) after a parameter name to specify its type.
  2. Use -> to describe the return type.

Example:

def add_numbers(a: int, b: int) -> int:
    return a + b

  • a: int and b: int mean the inputs are integers.
  • -> int tells you the function returns an integer.

Mini-Project: Task Manager

Let’s build a small project to see function annotations in action.

Objective: Create a Task Manager where you can:

  1. Add tasks with a due date.
  2. List all tasks.
  3. Mark tasks as complete.

Step 1: Plan the Project

We need:

  1. A class to store task details.
  2. Functions to add, list, and mark tasks complete.
  3. Function annotations to specify the expected data types.

Step 2: Write the Code

from typing import List, Optional
from datetime import datetime

# Task class to store task details
class Task:
    def __init__(self, title: str, due_date: Optional[datetime] = None):
        self.title: str = title
        self.due_date: Optional[datetime] = due_date
        self.is_completed: bool = False

    def mark_complete(self) -> None:
        self.is_completed = True

# Task Manager to handle multiple tasks
class TaskManager:
    def __init__(self):
        self.tasks: List[Task] = []

    def add_task(self, title: str, due_date: Optional[datetime] = None) -> None:
        new_task = Task(title, due_date)
        self.tasks.append(new_task)

    def list_tasks(self) -> List[str]:
        return [
            f"{task.title} - {'Completed' if task.is_completed else 'Pending'} - Due: {task.due_date if task.due_date else 'No due date'}"
            for task in self.tasks
        ]

    def mark_task_complete(self, title: str) -> bool:
        for task in self.tasks:
            if task.title == title:
                task.mark_complete()
                return True
        return False

# Example Usage
if __name__ == "__main__":
    manager = TaskManager()

    # Adding tasks
    manager.add_task("Complete Python project", datetime(2025, 1, 15))
    manager.add_task("Read Python documentation")

    # List tasks
    print("Tasks:")
    for task in manager.list_tasks():
        print(task)

    # Mark a task as complete
    manager.mark_task_complete("Complete Python project")

    # List tasks again
    print("\nUpdated Tasks:")
    for task in manager.list_tasks():
        print(task)

Step 3: How It Works

  1. Task Class:
    • Stores task details like title, due date, and completion status.
    • Uses annotations (title: str, due_date: Optional[datetime]) to specify input types.
  2. Task Manager Class:
    • Handles adding, listing, and updating tasks.
    • Uses annotations like List[Task] and Optional[datetime] to describe data.
  3. Example Usage:
    • You can add tasks with or without due dates.
    • View the list of tasks.
    • Mark a task as complete and see the updated list.

Interview Questions and Answers


Amazon

Q1: How do annotations help in team projects?
A1: They act as inline documentation, making it easier for teams to understand how to use functions correctly.

Google

Q2: Can you use annotations with optional arguments?
A2: Yes, you can use Optional. Example:

def greet(name: Optional[str] = None) -> str:
    return f"Hello, {name or 'Guest'}!"

Zoho

Q3: How would you annotate a function that takes a dictionary?
A3: Use Dict. Example:

from typing import Dict

def summarize_data(data: Dict[str, int]) -> str:
    return f"Total: {sum(data.values())}"

Infosys

Q4: Do annotations enforce type checking at runtime?
A4: No, annotations are only hints. Python does not enforce them during execution.

TCS

Q5: How do you annotate a function that returns a list of strings?
A5: Use List[str]. Example:

from typing import List

def get_names() -> List[str]:
    return ["Alice", "Bob", "Charlie"]

Conclusion

Python function annotations make your code clear and easy to understand. By practicing with projects like the Task Manager, you’ll see how annotations improve code quality and collaboration. Start using function annotations today to write better Python code!

Function Annotations