Skip to content

Innlegg

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

16. februar 2025 • 3 min lesing

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

Avhengighetsineksjon er en hovedstøtte 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 avhengighetsineksjon igjen?

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

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

I statiske språk som C# og Java brukes avhengighetsineksjon mye for å redusere koblingen og lette testing. Faktisk vil du finne avhengighetsineksjonsrammeverk hvis eneste formål er å opprettholde avhengigheter og deres forhold til hverandre.

Avhengighetsineksjon tjener to hovedformål:

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

For det andre tillater avhengighet på en abstraksjon at ulike implementeringer, inkludert mocks for testing, kan sendes inn i klassen eller funksjonen.

La meg demonstrere med noe kode:

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

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

# After  
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 avhengighetsineksjon i sin enkleste form. Selv om konseptet er enkelt, ligger dens kraft i å muliggjøre fleksible design.

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

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

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

date_string = "2023-10-01"  # Example date string
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)

På linje 6 (birthday < turn_of_the_century) tillater avhengighetsineksjon oss å bytte implementeringer enkelt basert på ulike forhold. Selv om denne fleksibiliteten er verdifull for produksjonskode, er en av de mest vanlige bruken for avhengighetsineksjon, 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å det samme resultatet.

Interessant nok ble avhengighetsineksjon ikke mye brukt i Python-prosjektene jeg har arbeidet med. Fra en bakgrunn med statiske språk var jeg overrasket – og det virket motintuitivt.

Imidlertid er det en grunn til denne begrensede adopsjonen. Pythons innebygde patch-funksjonalitet gir allerede utmerkede testmuligheter, noe som eliminerer en av avhengighetsineksjons hovedfordeler. Selv om avhengighetsineksjon fortsatt kan bidra til å redusere kompleksitet, har Python andre tilnærminger for å oppnå det samme målet.

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

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

Hvis du er interessert i å utforske avhengighetsineksjon 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 er en AI-ingeniør med nesten 30 års erfaring innen programvareutvikling. Han bygger praktiske AI-systemer—innholdspipelines, infrastrukturagenter og verktøy som løser virkelige problemer—og deler det han lærer underveis. Koble til ham på sosiale medier: X (@chuckconway) eller besøk ham på YouTube og på SubStack.

↑ Tilbake til toppen

Du kan også like