Skip to content

Beiträge

Kann Dependency Injection mich zu einem besseren Python-Programmierer machen?

16. Februar 2025 • 3 Min. Lesezeit

Kann Dependency Injection mich zu einem besseren Python-Programmierer machen?

Dependency Injection ist ein Grundpfeiler in statischen Sprachen, aber macht es Sinn, es in Python zu verwenden? Wird es mich zu einem besseren Python-Programmierer machen?

Und, warte, was ist nochmal Dependency Injection?

Zuerst beantworten wir die Frage: Was ist Dependency Injection (DI)?

Dependency Injection ist ein Pattern, das bei der Verwendung die Konstruktion eines Objekts außerhalb der Klasse verlagert. Stattdessen nimmt die Klasse eine Abhängigkeit zu einer Abstraktion auf.

In statischen Sprachen wie C# und Java wird Dependency Injection stark genutzt, um Kopplung zu reduzieren und Tests zu erleichtern. Tatsächlich findet man Dependency Injection Frameworks, deren einziger Zweck es ist, Abhängigkeiten und ihre Beziehungen zueinander zu verwalten.

Dependency Injection erfüllt zwei Hauptzwecke:

Erstens reduziert es die Komplexität, indem es eine Abhängigkeit zu einer Abstraktion aufnimmt.

Zweitens ermöglicht die Abhängigkeit von einer Abstraktion, dass verschiedene Implementierungen, einschließlich Mocks für Tests, in die Klasse oder Funktion übergeben werden können.

Lassen Sie mich das mit etwas Code demonstrieren:

# Vorher 
class User:
    def __init__(self):
        self.database = SqlServerDatabase()

    def get_details(self, user_id: int):
        self.database.get_user_details(user_id)

# Nachher  
class User:
    def __init__(self, database: Database):
        self.database = database

    def get_details(self, user_id: int):
        self.database.get_user_details(user_id)

Das ist Dependency Injection in ihrer einfachsten Form. Während das Konzept unkompliziert ist, liegt ihre Macht darin, flexible Designs zu ermöglichen.

Im Vorher-Beispiel ist die User-Klasse eng gekoppelt an die SqlServerDatabase-Klasse. Wenn wir die User-Klasse testen wollen, müssen wir eine neue SqlServerDatabase-Instanz erstellen.

Im Nachher-Beispiel ist die User-Klasse lose gekoppelt an die Database-Abstraktion. Wir können eine andere Implementierung der Database-Abstraktion an die User-Klasse übergeben.

Lassen Sie mich diese Flexibilität mit einem praktischen Beispiel demonstrieren, das zeigt, wie wir zwischen verschiedenen Datenbankimplementierungen wechseln können:

date_string = "2023-10-01"  # Beispiel-Datumsstring
date_format = "%Y-%m-%d"    # Input-String-Format
birthday = datetime.strptime(date_string, date_format) 
turn_of_the_century = datetime.strptime('2000-01-01', date_format)

database = PostgresDatabase("")

if birthday < turn_of_the_century:
    database = SqlServerDatabase("")

user = User(database=database)
user.get_details(user_id=1)

In Zeile 6 (birthday < turn_of_the_century) ermöglicht uns Dependency Injection, Implementierungen basierend auf verschiedenen Bedingungen einfach auszutauschen. Während diese Flexibilität für Produktionscode wertvoll ist, ist eine der häufigsten Verwendungen für Dependency Injection, besonders in statischen Sprachen, beim Testen.

Hier ist ein Beispiel:

class UserTests(unittest.TestCase):
    def test_is_authenticated(self):
        database = MockDatabase('connection_string')
        
        is_authenticated = User(database).is_authenticated('user', 'pass')

        self.assertTrue(is_authenticated)

Das ist ein einfaches Beispiel mit einer MockDatabase-Klasse. In Python könnten wir auch die eingebaute Mock-Klasse verwenden, um das gleiche Ergebnis zu erzielen.

Interessanterweise wurde Dependency Injection in den Python-Projekten, an denen ich gearbeitet habe, nicht weit verbreitet eingesetzt. Aus einem statischen Sprachenhintergrund kommend, war ich überrascht— und es schien kontraintuitiv.

Es gibt jedoch einen Grund für diese begrenzte Akzeptanz. Pythons eingebaute Patch-Funktionalität bietet bereits ausgezeichnete Testmöglichkeiten und eliminiert einen der Hauptvorteile von Dependency Injection. Während Dependency Injection immer noch dabei helfen kann, Komplexität zu reduzieren, hat Python andere Ansätze, um das gleiche Ziel zu erreichen.

Ich sage nicht, dass Dependency Injection nicht in Python verwendet werden sollte. Ganz im Gegenteil, wie alle Tools und Patterns gibt es einen Ort und eine Zeit, sie zu verwenden. Und Dependency Injection ist nur ein weiteres Tool in Ihrem Werkzeuggürtel, das die Qualität Ihres Codes verbessern wird.

Ich denke, Dependency Injection würde die Codequalität in den meisten Python-Projekten generell erhöhen.

Wenn Sie daran interessiert sind, Dependency Injection weiter zu erkunden, empfehle ich Ihnen, zwei beliebte Python-Frameworks zu betrachten:

  • Injector (github.com/python-injector/injector)
  • Dependency Injector (python-dependency-injector.ets-labs.org)

Autor: Chuck Conway ist spezialisiert auf Software-Engineering und Generative KI. Verbinden Sie sich mit ihm in den sozialen Medien: X (@chuckconway) oder besuchen Sie ihn auf YouTube.

↑ Zurück nach oben

Das könnte dir auch gefallen