Skip to content

Innlegg

Kan Dependency Injection gjøre meg til en bedre Python-programmerer?

16. februar 2025 • 3 min lesing

Kan Dependency Injection gjøre meg til en bedre Python-programmerer?

Dependency Injection er en grunnpilar i statiske språk, men gir det mening å bruke det i Python? Vil det gjøre meg til en bedre Python-programmerer?

Og vent, hva er dependency injection igjen?

Først, la oss svare på spørsmålet: Hva er dependency injection (DI)?

Dependency injection er et mønster som, når det brukes, flytter konstruksjonen av et objekt utenfor klassen. I stedet tar klassen en avhengighet til en abstraksjon.

I statiske språk som C# og Java brukes dependency injection mye for å redusere kobling og lette testing. Faktisk finner du dependency injection-rammeverk hvis eneste formål er å vedlikeholde avhengigheter og deres forhold til hverandre.

Dependency injection tjener to hovedformål:

For det første reduserer det kompleksitet ved å ta en avhengighet til en abstraksjon.

For det andre tillater avhengighet til en abstraksjon forskjellige implementasjoner, inkludert mocks for testing, å bli sendt inn i klassen eller funksjonen.

La meg demonstrere med litt kode:

# Før 
class User:
    def __init__(self):
        self.database = SqlServerDatabase()

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

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

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

Dette er dependency injection i sin enkleste form. Selv om konseptet er enkelt, ligger kraften i å muliggjøre fleksible design.

I Før-eksemplet er User-klassen tett koblet til SqlServerDatabase-klassen. Hvis vi vil teste User-klassen, må vi opprette en ny SqlServerDatabase-instans.

I Etter-eksemplet er User-klassen løst koblet til Database-abstraksjonen. Vi kan sende inn en annen implementasjon av Database-abstraksjonen til User-klassen.

La meg demonstrere denne fleksibiliteten med et praktisk eksempel som viser hvordan vi kan bytte mellom forskjellige databaseimplementasjoner:

date_string = "2023-10-01"  # Eksempel på datostreng
date_format = "%Y-%m-%d"    # Input strengformat
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)

På linje 6 (birthday < turn_of_the_century) lar dependency injection oss bytte implementasjoner enkelt basert på forskjellige betingelser. Selv om denne fleksibiliteten er verdifull for produksjonskode, er en av de vanligste bruksområdene for dependency injection, spesielt i statiske språk, i testing.

Her er et eksempel:

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)

Dette er et enkelt eksempel som bruker en MockDatabase-klasse. I Python kunne vi også bruke den innebygde Mock-klassen for å oppnå samme resultat.

Interessant nok ble ikke dependency injection mye brukt i Python-prosjektene jeg har jobbet med. Kommende fra en statisk språkbakgrunn var jeg overrasket— og det virket kontraintuitivt.

Det er imidlertid en grunn til denne begrensede adopsjonen. Pythons innebygde patch-funksjonalitet gir allerede utmerkede testmuligheter, noe som eliminerer en av dependency injections hovedfordeler. Selv om Dependency Injection fortsatt kan hjelpe med å redusere kompleksitet, har Python andre tilnærminger for å oppnå samme mål.

Jeg sier ikke at Dependency Injection ikke bør brukes i Python. Tvert imot, som alle verktøy og mønstre, er det en plass og tid for å bruke dem. Og Dependency Injection er bare et annet verktøy i verktøybeltet ditt som vil forbedre kvaliteten på koden din.

Jeg tror Dependency Injection generelt ville øke kodekvaliteten i de fleste Python-prosjekter.

Hvis du er interessert i å utforske Dependency Injection videre, anbefaler jeg å sjekke ut to populære Python-rammeverk:

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

Forfatter: Chuck Conway spesialiserer seg på programvareutvikling og Generativ AI. Koble til ham på sosiale medier: X (@chuckconway) eller besøk ham på YouTube.

↑ Tilbake til toppen

Du liker kanskje også