Umgang mit fehlenden oder ungültigen Funktionsargumenten in Python

PythonBeginner
Jetzt üben

Einführung

Funktionsargumente in Python sind ein grundlegender Aspekt der Programmierung, aber der Umgang mit fehlenden oder ungültigen Argumenten kann eine Herausforderung darstellen. Dieses Tutorial führt Sie durch die Handhabung von Funktionsargumenten in Python, vom Verständnis der Grundlagen bis zur Implementierung robuster Validierungs- und Fehlerbehandlungsstrategien. Am Ende werden Sie in der Lage sein, Python-Code zu schreiben, der Funktionsargumente elegant verwaltet und zu zuverlässigeren und wartungsfreundlicheren Anwendungen führt.

Grundlagen von Funktionsargumenten und Standardwerten verstehen

In Python sind Funktionen Blöcke wiederverwendbaren Codes, die bestimmte Aufgaben ausführen. Wenn Sie eine Funktion definieren, können Sie Parameter angeben, die die Funktion erwartet. Lassen Sie uns lernen, wie man Funktionen mit verschiedenen Arten von Argumenten einrichtet und wie man Standardwerte bereitstellt.

Erstellen unserer ersten Funktion

Beginnen wir damit, eine einfache Python-Datei zu erstellen, mit der wir arbeiten können. Navigieren Sie in der WebIDE zum Projektverzeichnis und erstellen Sie eine neue Datei namens function_args.py:

  1. Klicken Sie im WebIDE auf das Menü "Datei" ("File")
  2. Wählen Sie "Neue Datei" ("New File")
  3. Geben Sie function_args.py als Dateinamen ein
  4. Klicken Sie auf "OK"

Fügen wir nun eine einfache Funktion zu dieser Datei hinzu:

def greet(name):
    """A simple function that greets a person by name."""
    return f"Hello, {name}!"

## Call the function and print the result
result = greet("Alice")
print(result)

Speichern Sie die Datei (Strg+S oder Datei > Speichern) und führen Sie sie dann im Terminal aus:

python3 function_args.py

Sie sollten die Ausgabe sehen:

Hello, Alice!

Erforderliche Argumente verstehen

Im obigen Beispiel ist name ein erforderliches Argument. Wenn Sie versuchen, die Funktion aufzurufen, ohne dieses Argument anzugeben, löst Python einen Fehler aus.

Ändern wir unsere Datei, um dies zu demonstrieren:

def greet(name):
    """A simple function that greets a person by name."""
    return f"Hello, {name}!"

## This will work
result = greet("Alice")
print(result)

## This will raise an error
try:
    result = greet()
    print(result)
except TypeError as e:
    print(f"Error: {e}")

Speichern Sie die Datei und führen Sie sie aus:

python3 function_args.py

Ausgabe:

Hello, Alice!
Error: greet() missing 1 required positional argument: 'name'

Wie Sie sehen können, löst Python einen TypeError aus, wenn wir das erforderliche Argument nicht angeben.

Hinzufügen von Standardwerten

Um Argumente optional zu machen, können wir Standardwerte angeben. Aktualisieren wir unsere Funktion:

def greet(name="Guest"):
    """A function that greets a person by name, with a default value."""
    return f"Hello, {name}!"

## With an argument
result1 = greet("Alice")
print(result1)

## Without an argument - uses the default value
result2 = greet()
print(result2)

Speichern und ausführen:

python3 function_args.py

Ausgabe:

Hello, Alice!
Hello, Guest!

Jetzt funktioniert die Funktion sowohl mit als auch ohne Argument.

Mehrere Argumente mit Standardwerten

Erweitern wir unsere Funktion, um mehrere Argumente zu verarbeiten, einige mit Standardwerten:

def greet(name="Guest", message="Hello", punctuation="!"):
    """A function with multiple arguments and default values."""
    return f"{message}, {name}{punctuation}"

## Using all default values
print(greet())

## Providing only the name
print(greet("Alice"))

## Providing name and message
print(greet("Bob", "Hi"))

## Providing all arguments
print(greet("Charlie", "Welcome", "!!!"))

Speichern und ausführen:

python3 function_args.py

Ausgabe:

Hello, Guest!
Hello, Alice!
Hi, Bob!
Welcome, Charlie!!!

Verwendung von Schlüsselwortargumenten

Sie können Argumente auch nach Namen angeben, unabhängig von ihrer Reihenfolge:

def greet(name="Guest", message="Hello", punctuation="!"):
    """A function with multiple arguments and default values."""
    return f"{message}, {name}{punctuation}"

## Using keyword arguments
print(greet(message="Hey", name="David"))
print(greet(punctuation="...", message="Welcome back", name="Emma"))

Speichern und ausführen:

python3 function_args.py

Ausgabe:

Hey, David!
Welcome back, Emma...

Dies ist besonders nützlich, wenn eine Funktion viele Argumente hat und Sie nur einige davon angeben möchten.

Jetzt verstehen Sie, wie Sie Funktionen mit Standardargumenten erstellen und wie Sie Schlüsselwortargumente verwenden. Im nächsten Schritt werden wir fortgeschrittenere Möglichkeiten zur Handhabung fehlender oder ungültiger Funktionsargumente untersuchen.

Umgang mit fehlenden Argumenten mit *args und **kwargs

In Python müssen wir manchmal flexible Funktionen erstellen, die eine variable Anzahl von Argumenten akzeptieren können. Um diese Fälle zu behandeln, bietet Python zwei spezielle Syntaxelemente: *args und **kwargs.

Erstellen einer neuen Python-Datei

Erstellen wir eine neue Datei, um mit diesen Konzepten zu arbeiten:

  1. Klicken Sie im WebIDE auf das Menü "Datei" ("File")
  2. Wählen Sie "Neue Datei" ("New File")
  3. Geben Sie flexible_args.py als Dateinamen ein
  4. Klicken Sie auf "OK"

*args verstehen

Die Syntax *args ermöglicht es einer Funktion, eine beliebige Anzahl von Positionsargumenten (positional arguments) zu akzeptieren, die in einem Tupel gesammelt werden.

Fügen Sie den folgenden Code zu flexible_args.py hinzu:

def sum_numbers(*args):
    """A function that sums up any number of arguments."""
    result = 0
    for num in args:
        result += num
    return result

## Test the function with different numbers of arguments
print(f"Sum of 1, 2: {sum_numbers(1, 2)}")
print(f"Sum of 1, 2, 3, 4, 5: {sum_numbers(1, 2, 3, 4, 5)}")
print(f"No arguments: {sum_numbers()}")

Speichern Sie die Datei und führen Sie sie aus:

python3 flexible_args.py

Ausgabe:

Sum of 1, 2: 3
Sum of 1, 2, 3, 4, 5: 15
No arguments: 0

Dies zeigt, wie *args eine beliebige Anzahl von Argumenten verarbeiten kann, einschließlich gar keine. Innerhalb der Funktion ist args ein Tupel, das alle bereitgestellten Argumente enthält.

**kwargs verstehen

Die Syntax **kwargs ermöglicht es einer Funktion, eine beliebige Anzahl von Schlüsselwortargumenten (keyword arguments) zu akzeptieren, die in einem Dictionary gesammelt werden.

Fügen wir unserer Datei eine weitere Funktion hinzu:

def build_profile(**kwargs):
    """A function that builds a user profile from keyword arguments."""
    profile = {}

    ## Add required fields with defaults
    profile["name"] = kwargs.get("name", "Anonymous")
    profile["age"] = kwargs.get("age", "Not specified")

    ## Add any additional fields
    for key, value in kwargs.items():
        if key not in ["name", "age"]:
            profile[key] = value

    return profile

## Test the function with different keyword arguments
print("Basic profile:", build_profile())
print("Full profile:", build_profile(name="Alice", age=30, occupation="Developer", location="New York"))
print("Custom fields:", build_profile(hobby="Reading", favorite_color="Blue"))

Speichern und ausführen:

python3 flexible_args.py

Ausgabe:

Basic profile: {'name': 'Anonymous', 'age': 'Not specified'}
Full profile: {'name': 'Alice', 'age': 30, 'occupation': 'Developer', 'location': 'New York'}
Custom fields: {'name': 'Anonymous', 'age': 'Not specified', 'hobby': 'Reading', 'favorite_color': 'Blue'}

Beachten Sie, wie kwargs.get("key", default_value) es uns ermöglicht, Werte mit Standardwerten abzurufen, wenn sie nicht existieren.

Kombinieren von Required, Default, *args und **kwargs

Erstellen wir eine komplexere Funktion, die all diese Arten von Argumenten kombiniert:

def format_message(recipient, message="Hello", *args, **kwargs):
    """
    A function that formats a message with various customization options.
    - recipient: Required - who the message is for
    - message: Default greeting
    - *args: Additional message parts
    - **kwargs: Formatting options
    """
    ## Start with the basic message
    full_message = f"{message}, {recipient}!"

    ## Add any additional message parts
    if args:
        full_message += " " + " ".join(args)

    ## Apply formatting options
    if kwargs.get("upper", False):
        full_message = full_message.upper()

    if kwargs.get("wrap", False):
        full_message = f"[{full_message}]"

    return full_message

## Test with different combinations
print(format_message("Alice"))
print(format_message("Bob", "Hi"))
print(format_message("Charlie", "Welcome", "Hope", "you", "are", "well"))
print(format_message("David", "Greetings", upper=True))
print(format_message("Emma", wrap=True))
print(format_message("Frank", "Hey", "How's it going?", upper=True, wrap=True))

Speichern und ausführen:

python3 flexible_args.py

Ausgabe:

Hello, Alice!
Hi, Bob!
Welcome, Charlie! Hope you are well
GREETINGS, DAVID!
[Hello, Emma!]
[HEY, FRANK! HOW'S IT GOING?]

Dieses Beispiel zeigt, wie man alle Arten von Funktionsargumenten zusammen verwendet:

  1. recipient ist ein erforderliches Positionsargument (positional argument)
  2. message hat einen Standardwert, wodurch es optional ist
  3. *args erfasst alle zusätzlichen Positionsargumente
  4. **kwargs erfasst alle Schlüsselwortargumente

Durch die Kombination dieser Ansätze können Sie hochflexible Funktionen erstellen, die fehlende oder optionale Argumente elegant behandeln.

Validieren von Funktionsargumenten

Bei der Erstellung von Funktionen in Python ist es wichtig, zu überprüfen, ob die an Ihre Funktionen übergebenen Argumente gültig sind, bevor Sie mit der Hauptlogik der Funktion fortfahren. In diesem Schritt lernen wir verschiedene Techniken zur Validierung von Funktionsargumenten kennen.

Erstellen einer neuen Python-Datei

Erstellen wir eine neue Datei, um mit Validierungskonzepten zu arbeiten:

  1. Klicken Sie im WebIDE auf das Menü "Datei" ("File")
  2. Wählen Sie "Neue Datei" ("New File")
  3. Geben Sie validate_args.py als Dateinamen ein
  4. Klicken Sie auf "OK"

Grundlegende Validierung mit Bedingungen

Der einfachste Weg, Argumente zu validieren, ist die Verwendung von bedingten Anweisungen. Beginnen wir mit einigen grundlegenden Validierungen:

def calculate_rectangle_area(length, width):
    """Calculate the area of a rectangle, validating inputs."""
    ## Validate that inputs are numbers
    if not isinstance(length, (int, float)):
        raise TypeError("Length must be a number")
    if not isinstance(width, (int, float)):
        raise TypeError("Width must be a number")

    ## Validate that inputs are positive
    if length <= 0:
        raise ValueError("Length must be positive")
    if width <= 0:
        raise ValueError("Width must be positive")

    ## Calculate the area
    return length * width

## Test with valid inputs
try:
    area = calculate_rectangle_area(5, 3)
    print(f"Area of rectangle: {area}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with invalid types
try:
    area = calculate_rectangle_area("5", 3)
    print(f"Area of rectangle: {area}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with invalid values
try:
    area = calculate_rectangle_area(5, -3)
    print(f"Area of rectangle: {area}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

Speichern und ausführen:

python3 validate_args.py

Ausgabe:

Area of rectangle: 15
Error: Length must be a number
Error: Width must be positive

Diese Funktion validiert sowohl die Typen als auch die Werte ihrer Argumente, bevor Berechnungen durchgeführt werden. Wenn ungültige Argumente erkannt werden, werden entsprechende Fehlermeldungen ausgelöst.

Verwenden von Assertions zur Validierung

Eine andere Möglichkeit, Argumente zu validieren, ist die Verwendung von Assertions. Assertions sind Anweisungen, die einen AssertionError auslösen, wenn eine Bedingung nicht erfüllt ist:

def calculate_discount(price, discount_percent):
    """Calculate the discounted price."""
    ## Assert that inputs are valid
    assert isinstance(price, (int, float)), "Price must be a number"
    assert isinstance(discount_percent, (int, float)), "Discount must be a number"
    assert price >= 0, "Price cannot be negative"
    assert 0 <= discount_percent <= 100, "Discount must be between 0 and 100"

    ## Calculate the discount
    discount_amount = price * (discount_percent / 100)
    return price - discount_amount

## Test with valid inputs
try:
    discounted_price = calculate_discount(100, 20)
    print(f"Discounted price: ${discounted_price}")
except AssertionError as e:
    print(f"Error: {e}")

## Test with invalid discount percentage
try:
    discounted_price = calculate_discount(100, 120)
    print(f"Discounted price: ${discounted_price}")
except AssertionError as e:
    print(f"Error: {e}")

Speichern und ausführen:

python3 validate_args.py

Ausgabe:

Discounted price: $80.0
Error: Discount must be between 0 and 100

Assertions sind nützlich für die Entwicklung und das Debugging, können aber im Produktionscode deaktiviert werden, daher sind sie nicht immer die beste Wahl für die Validierung in realen Anwendungen.

Verwenden von Typ-Hinweisen zur Dokumentation

Python 3.5+ unterstützt Typ-Hinweise (type hints), die helfen können, die erwarteten Typen von Funktionsargumenten und Rückgabewerten zu dokumentieren. Während Typ-Hinweise selbst keine Laufzeitvalidierung durchführen, bieten sie nützliche Dokumentation und können von externen Tools wie mypy überprüft werden:

def calculate_average(numbers: list[float]) -> float:
    """Calculate the average of a list of numbers."""
    if not numbers:
        raise ValueError("Cannot calculate average of empty list")

    if not all(isinstance(n, (int, float)) for n in numbers):
        raise TypeError("All elements must be numbers")

    return sum(numbers) / len(numbers)

## Test with valid input
try:
    avg = calculate_average([1, 2, 3, 4, 5])
    print(f"Average: {avg}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with empty list
try:
    avg = calculate_average([])
    print(f"Average: {avg}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with non-numeric elements
try:
    avg = calculate_average([1, 2, "3", 4, 5])
    print(f"Average: {avg}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

Speichern und ausführen:

python3 validate_args.py

Ausgabe:

Average: 3.0
Error: Cannot calculate average of empty list
Error: All elements must be numbers

Beachten Sie, dass die Typ-Hinweise (list[float] und -> float) selbst keine Validierung durchführen – wir müssen immer noch unseren eigenen Validierungscode schreiben. Sie dienen als Dokumentation und können von externen Tools überprüft werden.

Erstellen einer robusten Funktion mit Validierung

Wenden wir nun all diese Techniken an, um eine robuste Funktion zu erstellen, die die Gesamtkosten von Artikeln mit einem Rabatt berechnet:

def calculate_total_cost(items=None, tax_rate=0, discount=0):
    """
    Calculate the total cost of items with tax and discount.

    Args:
        items: List of (item_name, price) tuples
        tax_rate: Tax rate percentage (0-100)
        discount: Discount percentage (0-100)

    Returns:
        A dictionary with the total, subtotal, tax amount, and discount amount
    """
    ## Validate items
    if items is None:
        items = []

    if not isinstance(items, list):
        raise TypeError("Items must be a list")

    ## Validate each item in the list
    for i, item in enumerate(items):
        if not isinstance(item, tuple) or len(item) != 2:
            raise ValueError(f"Item {i} must be a tuple of (name, price)")

        name, price = item
        if not isinstance(name, str):
            raise TypeError(f"Name of item {i} must be a string")
        if not isinstance(price, (int, float)):
            raise TypeError(f"Price of item {i} must be a number")
        if price < 0:
            raise ValueError(f"Price of item {i} cannot be negative")

    ## Validate tax_rate and discount
    if not isinstance(tax_rate, (int, float)):
        raise TypeError("Tax rate must be a number")
    if not isinstance(discount, (int, float)):
        raise TypeError("Discount must be a number")

    if not (0 <= tax_rate <= 100):
        raise ValueError("Tax rate must be between 0 and 100")
    if not (0 <= discount <= 100):
        raise ValueError("Discount must be between 0 and 100")

    ## Calculate the total
    subtotal = sum(price for _, price in items)
    discount_amount = subtotal * (discount / 100)
    tax_amount = (subtotal - discount_amount) * (tax_rate / 100)
    total = subtotal - discount_amount + tax_amount

    return {
        "subtotal": subtotal,
        "discount_amount": discount_amount,
        "tax_amount": tax_amount,
        "total": total
    }

## Test with valid inputs
shopping_cart = [
    ("Laptop", 1000),
    ("Mouse", 25),
    ("Keyboard", 45)
]

try:
    result = calculate_total_cost(shopping_cart, tax_rate=8.5, discount=10)
    print("Shopping Cart Total:")
    for key, value in result.items():
        print(f"  {key.replace('_', ' ').title()}: ${value:.2f}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with invalid item
try:
    invalid_cart = [
        ("Laptop", 1000),
        ("Mouse", "twenty-five"),  ## Invalid price
        ("Keyboard", 45)
    ]
    result = calculate_total_cost(invalid_cart)
    print(result)
except (TypeError, ValueError) as e:
    print(f"Error with invalid item: {e}")

Speichern und ausführen:

python3 validate_args.py

Ausgabe:

Shopping Cart Total:
  Subtotal: $1070.00
  Discount Amount: $107.00
  Tax Amount: $81.86
  Total: $1044.86
Error with invalid item: Price of item 1 must be a number

Diese Funktion demonstriert eine robuste Validierung durch:

  1. Überprüfen der Typen aller Eingaben
  2. Validieren des Bereichs numerischer Werte
  3. Bereitstellen detaillierter Fehlermeldungen
  4. Festlegen sinnvoller Standardwerte für optionale Parameter
  5. Verwenden von Docstrings zur Dokumentation der erwarteten Eingaben und Rückgabewerte

Durch die Implementierung einer gründlichen Validierung in Ihren Funktionen können Sie Fehler verhindern, den Benutzern ein besseres Feedback geben und Ihren Code robuster und wartungsfreundlicher machen.

Erstellen einer vollständigen Anwendung

Nachdem wir verschiedene Techniken zur Handhabung und Validierung von Funktionsargumenten gelernt haben, wollen wir diese Fähigkeiten anwenden, um eine einfache, aber vollständige Anwendung zu erstellen. Wir erstellen ein einfaches Ausgabenverfolgungssystem, das gute Praktiken für die Handhabung von Funktionsargumenten demonstriert.

Erstellen der Anwendungsdatei

Erstellen wir eine neue Python-Datei für unseren Ausgaben-Tracker:

  1. Klicken Sie im WebIDE auf das Menü "Datei" ("File")
  2. Wählen Sie "Neue Datei" ("New File")
  3. Geben Sie expense_tracker.py als Dateinamen ein
  4. Klicken Sie auf "OK"

Entwerfen der Ausgaben-Tracker-Funktionen

Unser Ausgaben-Tracker verfügt über mehrere Funktionen, die verschiedene Aspekte der Ausgabenverwaltung handhaben:

def create_expense(description, amount, category=None, date=None):
    """
    Create a new expense entry.

    Args:
        description (str): Description of the expense
        amount (float): The amount spent
        category (str, optional): Category of the expense
        date (str, optional): The date in YYYY-MM-DD format

    Returns:
        dict: An expense entry
    """
    ## Validate description
    if not isinstance(description, str):
        raise TypeError("Description must be a string")
    if not description:
        raise ValueError("Description cannot be empty")

    ## Validate amount
    if not isinstance(amount, (int, float)):
        raise TypeError("Amount must be a number")
    if amount <= 0:
        raise ValueError("Amount must be positive")

    ## Create the expense dictionary
    expense = {
        "description": description,
        "amount": float(amount),
        "category": category or "Uncategorized",
        "date": date or "Not specified"
    }

    return expense


def add_expense_to_list(expenses, **kwargs):
    """
    Add a new expense to the expenses list.

    Args:
        expenses (list): The list of expenses
        **kwargs: The expense details to be passed to create_expense

    Returns:
        list: The updated list of expenses
    """
    ## Validate the expenses list
    if not isinstance(expenses, list):
        raise TypeError("Expenses must be a list")

    ## Extract required arguments
    if "description" not in kwargs:
        raise ValueError("Expense description is required")
    if "amount" not in kwargs:
        raise ValueError("Expense amount is required")

    ## Create the expense and add it to the list
    expense = create_expense(
        kwargs["description"],
        kwargs["amount"],
        kwargs.get("category"),
        kwargs.get("date")
    )

    expenses.append(expense)
    return expenses


def get_total_expenses(expenses, category=None):
    """
    Calculate the total amount of expenses, optionally filtered by category.

    Args:
        expenses (list): The list of expenses
        category (str, optional): Filter by this category if provided

    Returns:
        float: The total amount
    """
    ## Validate the expenses list
    if not isinstance(expenses, list):
        raise TypeError("Expenses must be a list")

    ## Calculate the total
    if category:
        return sum(e["amount"] for e in expenses if e["category"] == category)
    else:
        return sum(e["amount"] for e in expenses)


def get_expense_summary(expenses):
    """
    Get a summary of expenses by category.

    Args:
        expenses (list): The list of expenses

    Returns:
        dict: A dictionary with categories as keys and total amounts as values
    """
    ## Validate the expenses list
    if not isinstance(expenses, list):
        raise TypeError("Expenses must be a list")

    ## Create the summary
    summary = {}
    for expense in expenses:
        category = expense["category"]
        if category in summary:
            summary[category] += expense["amount"]
        else:
            summary[category] = expense["amount"]

    return summary

Verwenden unseres Ausgaben-Trackers

Verwenden wir nun unsere Funktionen, um einige Ausgaben zu verfolgen:

def print_expense_summary(summary):
    """Print a formatted summary of expenses by category."""
    print("\nExpense Summary by Category:")
    print("-" * 30)
    for category, amount in summary.items():
        print(f"{category}: ${amount:.2f}")
    print("-" * 30)
    print(f"Total: ${sum(summary.values()):.2f}")

## Initialize an empty expenses list
expenses = []

## Add some expenses
try:
    ## Add with required arguments only
    expenses = add_expense_to_list(
        expenses,
        description="Groceries",
        amount=45.75
    )

    ## Add with all arguments
    expenses = add_expense_to_list(
        expenses,
        description="Movie tickets",
        amount=25.00,
        category="Entertainment",
        date="2023-11-15"
    )

    ## Add another expense
    expenses = add_expense_to_list(
        expenses,
        description="Dinner",
        amount=65.40,
        category="Food",
        date="2023-11-14"
    )

    ## Add with default category
    expenses = add_expense_to_list(
        expenses,
        description="Gas",
        amount=35.80,
        date="2023-11-16"
    )

    ## Display all expenses
    print("All Expenses:")
    for i, expense in enumerate(expenses, 1):
        print(f"{i}. {expense['description']}: ${expense['amount']:.2f} " +
              f"({expense['category']}, {expense['date']})")

    ## Get and display the total
    total = get_total_expenses(expenses)
    print(f"\nTotal expenses: ${total:.2f}")

    ## Get and display expenses for a specific category
    food_total = get_total_expenses(expenses, "Food")
    print(f"Food expenses: ${food_total:.2f}")

    ## Get and display the summary
    summary = get_expense_summary(expenses)
    print_expense_summary(summary)

except (TypeError, ValueError) as e:
    print(f"Error: {e}")

Fügen wir auch etwas Code hinzu, um die Fehlerbehandlung zu demonstrieren:

## Try some invalid inputs
print("\nTesting error handling:")

try:
    ## Invalid expense description
    expenses = add_expense_to_list(expenses, description="", amount=10)
except ValueError as e:
    print(f"Caught error: {e}")

try:
    ## Invalid expense amount
    expenses = add_expense_to_list(expenses, description="Coffee", amount=-5)
except ValueError as e:
    print(f"Caught error: {e}")

try:
    ## Missing required argument
    expenses = add_expense_to_list(expenses, description="Coffee")
except ValueError as e:
    print(f"Caught error: {e}")

Speichern Sie die Datei und führen Sie sie aus:

python3 expense_tracker.py

Erwartete Ausgabe:

All Expenses:
1. Groceries: $45.75 (Uncategorized, Not specified)
2. Movie tickets: $25.00 (Entertainment, 2023-11-15)
3. Dinner: $65.40 (Food, 2023-11-14)
4. Gas: $35.80 (Uncategorized, 2023-11-16)

Total expenses: $171.95
Food expenses: $65.40

Expense Summary by Category:
------------------------------
Uncategorized: $81.55
Entertainment: $25.00
Food: $65.40
------------------------------
Total: $171.95

Testing error handling:
Caught error: Description cannot be empty
Caught error: Amount must be positive
Caught error: Expense amount is required

Anwendungsüberprüfung

Unser Ausgaben-Tracker demonstriert mehrere wichtige Konzepte:

  1. Argumentvalidierung (Argument validation): Jede Funktion validiert ihre Argumente, um sicherzustellen, dass sie die erwarteten Typen und Einschränkungen erfüllen.

  2. Standardwerte (Default values): Wir verwenden Standardwerte, um bestimmte Argumente optional zu machen, wie z. B. category und date.

  3. Erforderliche Argumente (Required arguments): Für wesentliche Informationen wie description und amount stellen wir sicher, dass diese bereitgestellt und gültig sind.

  4. Schlüsselwortargumente (Keyword arguments): Die Funktion add_expense_to_list verwendet **kwargs, um Ausgabendetails auf flexible Weise zu akzeptieren.

  5. Fehlerbehandlung (Error handling): Wir verwenden geeignete Ausnahmen mit aussagekräftigen Fehlermeldungen, um das Debuggen zu erleichtern.

  6. Docstrings: Jede Funktion enthält einen Docstring, der ihren Zweck, ihre Argumente und Rückgabewerte erklärt.

Durch die Anwendung dieser Techniken haben wir eine robuste Anwendung erstellt, die Funktionsargumente auf zuverlässige und benutzerfreundliche Weise verarbeitet. Dieser Ansatz hilft, Fehler zu vermeiden, die Wartbarkeit des Codes zu verbessern und klares Feedback zu geben, wenn etwas schief geht.

Zusammenfassung

In diesem Tutorial haben Sie wesentliche Techniken zur Handhabung fehlender oder ungültiger Funktionsargumente in Python gelernt:

  1. Grundlegendes zu Funktionsargumenten und Standardwerten (Understanding basic function arguments and defaults): Sie haben verschiedene Arten von Funktionsargumenten untersucht, darunter erforderliche Argumente, optionale Argumente mit Standardwerten und Schlüsselwortargumente. Diese Grundlage hilft Ihnen, Funktionen zu entwerfen, die sowohl flexibel als auch benutzerfreundlich sind.

  2. Handhabung variabler Argumentanzahlen (Handling variable numbers of arguments): Sie haben gelernt, wie man *args und **kwargs verwendet, um Funktionen zu erstellen, die eine beliebige Anzahl von Argumenten akzeptieren können, wodurch Ihre Funktionen anpassungsfähiger an verschiedene Anwendungsfälle werden.

  3. Validieren von Funktionsargumenten (Validating function arguments): Sie haben verschiedene Validierungstechniken implementiert, um sicherzustellen, dass Argumente die erwarteten Typen und Einschränkungen erfüllen, wodurch Fehler vermieden und klare Fehlermeldungen bereitgestellt werden.

  4. Erstellen einer vollständigen Anwendung (Building a complete application): Sie haben diese Konzepte angewendet, um eine praktische Ausgabenverfolgungsanwendung zu erstellen, die zeigt, wie eine ordnungsgemäße Argumentbehandlung zu robustem und wartbarem Code führt.

Diese Fähigkeiten sind grundlegend für das Schreiben von zuverlässigem Python-Code. Durch die korrekte Handhabung von Funktionsargumenten können Sie Funktionen erstellen, die flexibler, einfacher zu verwenden und weniger fehleranfällig sind. Auf Ihrem weiteren Weg mit Python werden Ihnen diese Techniken helfen, anspruchsvollere Anwendungen zu erstellen, die unerwartete Eingaben und Sonderfälle problemlos verarbeiten können.