Type Hinting in Python: Default Values and Optional Types

Type hinting allows you to specify expected types for variables, function arguments, and return values.

This tutorial explains how to use type hinting with default values, optional types, collections, custom classes, and function annotations.

 

 

Type Hints with Default Values

You can use the syntax variable_name: type = default_value to define variables with both type hints and default values.

employee_name: str = "Amr"
print(employee_name)

Output:

Amr

This code defines a string variable employee_name with a default value of "Amr". When printed, it displays the value.

 

Using Optional[] for parameters that can be None

The Optional type from the typing module is used for parameters that might also accept None as a value.

from typing import Optional
def get_discount_code(user_id: Optional[int] = None) -> str:
    if user_id is None:
        return "NEWUSER"
    return f"DISCOUNT{user_id}"
print(get_discount_code())
print(get_discount_code(123))

Output:

NEWUSER
DISCOUNT123

The function get_discount_code returns "NEWUSER" when no user_id is provided (default is None). Otherwise, it returns a discount code using the user_id.

 

Type Hints for Collections

You can specify the types of elements in collections using List, Dict, and Set from the typing module.

from typing import List, Dict

# List with type hints and default values
customer_names: List[str] = ["Ahmed", "Sara", "Mona"]

# Dictionary with type hints and default values
customer_details: Dict[int, str] = {1: "Ahmed", 2: "Sara"}
print(customer_names)
print(customer_details)

Output:

['Ahmed', 'Sara', 'Mona']
{1: 'Ahmed', 2: 'Sara'}

customer_names is a list of strings with default values. customer_details is a dictionary with integer keys and string values.

Nested collections

For nested collections, use type hints to specify types of inner elements.

from typing import List, Dict

# Nested collections with type hints
nested_data: List[Dict[str, int]] = [{"age": 30}, {"age": 25}]
print(nested_data)

Output:

[{'age': 30}, {'age': 25}]

nested_data is a list of dictionaries where each dictionary has a string key ("age") and an integer value.

 

Type Hints for Custom Classes and Objects

You can use custom class names as types and provide default instances.

class Customer:
    def __init__(self, name: str, balance: float = 0.0):
        self.name = name
        self.balance = balance

# Using type hint for a custom class
def get_customer_details(customer: Customer = Customer("Unknown")) -> str:
    return f"Name: {customer.name}, Balance: {customer.balance}"
default_customer = get_customer_details()
specific_customer = get_customer_details(Customer("Eman", 100.0))
print(default_customer)
print(specific_customer)

Output:

Name: Unknown, Balance: 0.0
Name: Eman, Balance: 100.0

The function get_customer_details uses Customer as a type hint.

A default Customer instance is provided when no specific instance is passed.

 

Function Annotations with Default Values

Return type annotations

You can combine return type annotations with default values for a clear function signature.

def calculate_tax(amount: float = 100.0) -> float:
    return amount * 0.15
print(calculate_tax())
print(calculate_tax(200.0))

Output:

15.0
30.0

The function calculate_tax takes a float as input, has a default value of 100.0, and returns a float as output.

Multiple parameters with type hints and default values

Combine multiple arguments with type hints and defaults.

def generate_invoice(customer: str, total: float = 0.0, discount: float = 0.1) -> str:
    final_amount = total * (1 - discount)
    return f"Customer: {customer}, Final Amount: {final_amount:.2f}"
print(generate_invoice("Nour"))
print(generate_invoice("Youssef", 200.0, 0.2))

Output:

Customer: Nour, Final Amount: 0.00
Customer: Youssef, Final Amount: 160.00

The function generate_invoice calculates a final amount using the total and discount values and defaults them if not provided.

Leave a Reply

Your email address will not be published. Required fields are marked *