Wymuszanie typów w konstruktorze

0

Hej. Dopiero zaczynam z Pythonem i do tej pory nie miałem za dużo do czynienia z dynamicznym typowaniem. Czy faktycznie jeśli chcę w konstruktorze mieć zabezpieczenie przed stworzeniem obiektu z niewłaściwym typem danych, to powinienem do każdego pola dodawać:

class Book:
    def __init__(self, title: str, author: str, year: int, isbn: str, genre: str):
        if not isinstance(title, str):
            raise TypeError("Title must be a string")
        if not isinstance(author, str):
            raise TypeError("Author must be a string")
        if not isinstance(year, int):
            raise TypeError("Year must be an integer")
        if not isinstance(isbn, str):
            raise TypeError("ISBN must be a string")
        if not isinstance(genre, str):
            raise TypeError("Genre must be a string")
        
        self.title = title
        self.author = author
        self.year = year
        self.isbn = isbn
        self.genre = genre

tak jak mi radzi GPT?

2

Jak dla mnie seria wywołań isinstance() to paranoja.
Już lepiej użyj normalny język ze statycznym typowaniem. Np. C#.

Zapytałem się chata, czy można bez isinstance().
Oto co odpisał:

W Pythonie możesz sprawdzać typy bez użycia isinstance() poprzez wykorzystanie adnotacji typów (ang. type hints) w połączeniu z narzędziami takimi jak mypy lub Pyright, które statycznie sprawdzają poprawność typów podczas tworzenia kodu. Dzięki temu błędy związane z typami można wykryć przed uruchomieniem programu.

1. Adnotacje typów:

W Pythonie możesz dodać adnotacje typów dla argumentów funkcji i zwracanych wartości, np.:

def dodaj_liczby(a: int, b: int) -> int:
    return a + b

Tutaj funkcja dodaj_liczby oczekuje, że oba argumenty będą typu int i zwróci wartość typu int. Jednak same adnotacje nie wymuszają typów podczas działania programu.

2. Statyczna weryfikacja typów z mypy:

Możesz użyć narzędzia takiego jak mypy, aby wymusić poprawność typów na podstawie adnotacji. Kiedy napiszesz kod z adnotacjami, możesz uruchomić mypy, aby sprawdzić, czy kod jest zgodny z oczekiwanymi typami.

Aby używać mypy:

  1. Zainstaluj mypy:
    pip install mypy
    
  2. Uruchom sprawdzanie typów:
    mypy twoj_plik.py
    

Przykład:

# twoj_plik.py
def dodaj_liczby(a: int, b: int) -> int:
    return a + b

dodaj_liczby(1, 2)    # Poprawne wywołanie
dodaj_liczby(1, '2')  # mypy zgłosi błąd, bo '2' to string

Kiedy uruchomisz mypy, zgłosi ono błąd dla drugiego wywołania, ponieważ '2' jest typu str, a nie int.

3. Egzekwowanie typów w czasie działania (opcjonalne):

Chociaż Python nie wymusza typów w czasie działania (bo to język dynamicznie typowany), możesz użyć bibliotek takich jak pydantic, enforce czy typeguard, aby weryfikować typy na podstawie adnotacji również w czasie działania.

Przykład z typeguard:

Najpierw instalujesz bibliotekę:

pip install typeguard

A następnie korzystasz z niej, aby sprawdzać typy podczas działania programu:

from typeguard import typechecked

@typechecked
def dodaj_liczby(a: int, b: int) -> int:
    return a + b

dodaj_liczby(1, 2)    # Działa poprawnie
dodaj_liczby(1, '2')  # Podczas działania zgłosi TypeError

W przypadku podania błędnych typów, typeguard podniesie wyjątek TypeError podczas działania programu.

Podsumowanie:

  • Adnotacje typów pomagają w statycznym sprawdzaniu typów.
  • Narzędzia takie jak mypy lub Pyright umożliwiają statyczne wymuszanie poprawności typów.
  • Dla wymuszenia typów w czasie działania można opcjonalnie użyć bibliotek takich jak typeguard.
1

Oprócz tego co napisał @Spine, możesz śledzić https://peps.python.org/topic/typing/ i wyrobić sobie pogląd, czego się spodziewać w przyszłości.

1
paranoise napisał(a):

Czy faktycznie jeśli chcę w konstruktorze mieć zabezpieczenie przed stworzeniem obiektu z niewłaściwym typem danych, to powinienem do każdego pola dodawać: [...]

Taka zagrywka nie za bardzo ma sens. Dużo lepiej jest napisać testy pod kod który tworzy instację Book.

1

Popatrz na to, to nie wygląda jak Python, to nie wygląda jak kod nawet, dla mnie to jest stack trace 🙃

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.