Najnowsze funkcje Pythona
Ten artykuł wyjaśnia najnowsze funkcje Pythona.
Opiszemy krok po kroku najważniejsze funkcje Pythona od wersji 3.12 do 3.13 z praktycznego punktu widzenia — pod kątem 'natychmiastowego użycia' w aplikacjach.
YouTube Video
Najnowsze funkcje Pythona
W ostatnich latach Python rozwijał się, kładąc nacisk nie tylko na 'łatwość pisania', ale także na 'niezawodność, szybkość i czytelność'. Poniżej przedstawiamy godne uwagi funkcje wprowadzone w wersjach Pythona od 3.12 do 3.13.
Znacząca poprawa komunikatów o błędach (Python 3.12)
W Pythonie 3.12 błędy są teraz wyświetlane w bardziej konkretny i wizualny sposób. Możesz natychmiast zidentyfikować, gdzie pojawiły się błędy, i znacznie skrócić czas debugowania.
1def calc_total(price, tax):
2 return price + price * tax
3
4result = calc_total(100, )- Brakujące argumenty są wyświetlane wraz z odpowiednią linią i miejscem, dzięki czemu nie pomylisz się przy szukaniu przyczyny.
Praktyczne użycie instrukcji 'match' (strukturalne dopasowywanie wzorców)
Instrukcja 'match' pozwala deklaratywnie opisywać złożone rozgałęzienia warunkowe i rozróżnianie struktur danych. Obsługa słowników i zagnieżdżonych struktur staje się szczególnie czytelna.
1user = {"status": "active", "name": "Alice"}
2
3match user:
4 case {"status": "active", "name": name}:
5 print(f"Welcome back, {name}!")
6 case {"status": "inactive"}:
7 print("Please activate your account.")
8 case _:
9 print("Unknown user status.")- Ponieważ możesz jednocześnie przeprowadzać rozgałęzienia warunkowe i wyodrębniać dane, zagnieżdżanie instrukcji if staje się zbędne.
Intuicyjne dopasowywanie wzorców do obsługi danych zagnieżdżonych
Instrukcja 'match' sprawdza się także w przypadku danych strukturalnych, takich jak JSON czy odpowiedzi API.
1data = {"user": {"name": "Bob", "age": 25}}
2
3match data:
4 case {"user": {"name": name, "age": age}}:
5 print(f"{name} is {age} years old.")- Możesz bezpiecznie wyodrębnić tylko potrzebne elementy, ograniczając konieczność pisania kodu defensywnego.
Ulepszony debug za pomocą f-stringów (notacja =` / Python 3.8 i nowsze, poprawiona użyteczność)
Dzięki f-stringom możesz teraz dodać znak =, aby jednocześnie wyświetlić wyrażenie i wynik jego oceny. Funkcja ta jest przeznaczona do debugowania i jest niezwykle przydatna, gdy chcesz szybko sprawdzić zawartość zmiennej.
1x = 10
2y = 20
3print(f"{x=}, {y=}, {x+y=}")- Ponieważ nazwy zmiennych i ich wartości są wyświetlane razem, tymczasowe debugowanie za pomocą instrukcji
print()staje się bardziej czytelne. - Możesz zapisywać logi i kod weryfikujący w bardziej zwięzły i czytelny sposób.
Uproszczone adnotacje typów i aliasy 'type' (Python 3.12: Nowa składnia aliasów typów)
W Pythonie 3.12 wprowadzono dedykowaną składnię do definiowania aliasów typów — instrukcję type. Dzięki temu adnotacje typów nie są jedynie informacją pomocniczą, lecz także elementem języka do wyraźnego wyrażania zamysłu projektowego.
1type UserId = int
2type UserName = str
3
4def greet(user_id: UserId, name: UserName) -> str:
5 return f"Hello, {name} (id={user_id})"- Nadając konkretne znaczenie takim typom jak
UserIdczyUserName, można wyraźniej zaznaczyć różnice ról, nawet jeśli oba wykorzystują ten sam typintlubstr. - Definicje typów stają się bardziej zwięzłe, co obniża koszt zrozumienia podczas przeglądu i utrzymania kodu.
- Wcześniej aliasy typów takie jak
UserId = intbyły tworzone poprzez przypisanie, lecz użycie instrukcjitypesprawia, że jasno widać, iż 'to jest definicja typu'. Szczególnie skutecznie poprawia to czytelność projektową w średnich i większych bazach kodu.
Naturalne adnotacje typów przy użyciu wbudowanych typów (uproszczone generyki od Pythona 3.9+)
Od Pythona 3.9 możesz bezpośrednio używać wbudowanych typów, takich jak list czy dict, jako generyków.
Pozwala to pisać intuicyjne i czytelne adnotacje typów bez importowania ich z modułu typing.
1def sum_numbers(numbers: list[int]) -> int:
2 return sum(numbers)
3
4print(sum_numbers([1, 2, 3, 4]))- Adnotacje typów pełnią funkcję nie 'ograniczenia', lecz 'dokumentacji wyjaśniającej zawartość przetwarzania'.
Bezpieczne łączenie metod za pomocą typu Self (Python 3.11 i nowsze)
Od Pythona 3.11 możesz określić Self jako typ zwrotny dla metod zwracających samą klasę.
Umożliwia to bezpieczne pisanie kodu łańcuchującego metody bez utraty informacji o typach.
1from typing import Self
2
3class Counter:
4 def __init__(self, value: int = 0) -> None:
5 self.value = value
6
7 def increment(self) -> Self:
8 self.value += 1
9 return self
10
11counter = Counter()
12counter.increment().increment()
13print(counter.value)- Nawet dla metod zwracających
selfpoprawny typ zwrotny zostaje zachowany. - IDE i narzędzia sprawdzające typy potrafią prawidłowo zrozumieć łańcuchowanie metod.
Bardziej przejrzysta manipulacja napisami (removeprefix / removesuffix | Python 3.9 i nowsze)
Od wersji 3.9 dodano specjalne metody str.removeprefix() i str.removesuffix(), aby bezpiecznie usuwać prefiksy i sufiksy z napisów. Dzięki nim możesz precyzyjnie wyrazić w kodzie zamiar 'usunięcia tylko początku lub końca' napisu.
1filename = "report_2026.txt"
2
3clean_name = filename.removeprefix("report_")
4name_without_ext = clean_name.removesuffix(".txt")
5
6print(name_without_ext)- Podany napis jest usuwany tylko wtedy, gdy występuje na początku lub końcu, co zapobiega przypadkowym podmianom.
- Takie podejście zwiększa czytelność i bezpieczeństwo w porównaniu do używania
replace()lub cięcia (slicing). - Szczególnie przy obsłudze 'napisów o określonym formacie', takich jak nazwy plików czy wstępne przetwarzanie URL, użyciu tych metod może znacznie zmniejszyć ryzyko błędów.
Niezawodne porównywanie napisów dla internacjonalizacji (str.casefold() | wsparcie Unicode)
str.casefold() w Pythonie to metoda do porównań nieczułych na wielkość znaków, uwzględniająca Unicode. W przeciwieństwie do prostych metod lower() lub upper(), normalizuje ona napisy, w tym konwersję znaków specyficznych dla języków.
1text1 = "Stra\u00dfe"
2text2 = "strasse"
3
4print(text1)
5print(text2)
6
7print(f"Comparison Result: {text1.casefold() == text2.casefold()}")- Potrafi prawidłowo obsłużyć różnice zależne od języka takie jak niemieckie
ßiss. - To niezbędna technika dla aplikacji opartych na wsparciu wielojęzycznym lub internacjonalizacji.
Standardowe wsparcie dla TOML (tomllib | Python 3.11 i nowsze)
Od Pythona 3.11 do biblioteki standardowej dodano moduł tomllib do odczytu plików konfiguracyjnych TOML. Zarządzanie konfiguracją można teraz realizować wyłącznie w Pythonie, bez polegania na zewnętrznych bibliotekach.
1import tomllib
2
3with open("config.toml", "rb") as f:
4 config = tomllib.load(f)
5
6print(config["database"]["host"])
7
8# config.toml
9# title = "TOML Example"
10# [database]
11# host = "192.168.1.1"
12# ports = [ 8001, 8001, 8002 ]- Zewnętrzne pakiety, takie jak
toml, nie są już potrzebne, co upraszcza zależności projektu. - Wczytywanie plików konfiguracyjnych zostało ustandaryzowane, co ułatwia dystrybucję, wdrażanie i obsługę środowisk CI.
Obsługa wyjątków dla ery przetwarzania równoległego (ExceptionGroup / except* | Python 3.11 i nowsze)
W Pythonie 3.11 wprowadzono ExceptionGroup, umożliwiający obsługę wielu wyjątków jednocześnie, oraz składnię except*, aby bezpiecznie zarządzać nimi w oddzielnych gałęziach. To nowa funkcja do obsługi 'równoczesnych błędów', które pojawiają się w przetwarzaniu asynchronicznym lub równoległym.
1def process(values):
2 errors = []
3 for v in values:
4 if v < 0:
5 errors.append(ValueError(f"Negative value: {v}"))
6 if errors:
7 raise ExceptionGroup("Invalid values", errors)
8
9try:
10 process([1, -2, -3])
11except* ValueError as e:
12 print("Handled:", e)- Teraz można zgłaszać i klasyfikować wiele wyjątków w ramach jednej operacji.
- Rozwiązuje to problem w przetwarzaniu asynchronicznym, gdzie do tej pory widoczny był tylko pierwszy błąd.
- W operacjach takich jak
asyncio.gather()lub przetwarzanie wsadowe równoległe może wystąpić jednocześnie wiele czynników awarii. UżycieExceptionGroupułatwia organizację zbierania błędów, logowania oraz strategii ponawiania prób.
Wydajność wzrasta po prostu po aktualizacji do najnowszej wersji
Od Pythona 3.11 wiele procesów zostało przyspieszonych dzięki optymalizacjom wewnętrznym.
1def count_up(n):
2 total = 0
3 for i in range(n):
4 total += i
5 return total
6
7print(count_up(1_000_000))- Ogromną zaletą jest to, że poprawa wydajności następuje bez konieczności przepisywania kodu.
Kontrola odśmiecania pamięci (jawne zarządzanie przez moduł gc)
W Pythonie użycie standardowego modułu gc pozwala tymczasowo wyłączyć lub ręcznie uruchomić odśmiecanie pamięci. To skuteczna technika optymalizacyjna w scenariuszach takich jak przetwarzanie wsadowe dużych zbiorów danych czy operacje krytyczne wydajnościowo.
1import gc
2
3gc.disable()
4# heavy batch processing
5gc.enable()
6gc.collect()- Ograniczenie zbędnych wywołań odśmiecania pamięci zmniejsza wahania czasu przetwarzania.
- Możesz jawnie wykonywać odśmiecanie w określonych odstępach, ułatwiając śledzenie wykorzystania pamięci.
- Ta technika nie powinna być stosowana jako domyślna optymalizacja; używaj jej tylko wtedy, gdy profilowanie wskaże, że GC jest wąskim gardłem. Dla większości aplikacji najlepiej polegać na automatycznym odśmiecaniu pamięci w Pythonie.
Podsumowanie
Dzięki ulepszonym komunikatom o błędach i rozwojowi adnotacji typów w wersjach od 3.12 do 3.13, zrozumienie i utrzymanie kodu stały się łatwiejsze niż kiedykolwiek. Dodatkowo, takie usprawnienia jak lepsze możliwości debugowania i wzrost wydajności dzięki optymalizacjom wewnętrznym bezpośrednio przyczyniają się do wzrostu produktywności w praktyce. Nie musisz korzystać ze wszystkich nowych funkcji naraz; praktyczniej jest zacząć od najnowszej wersji Pythona i stopniowo wdrażać wybrane funkcje w razie potrzeby. Stopniowe wprowadzanie tych funkcji prowadzi do powstania bardziej czytelnego i niezawodnego kodu w Pythonie.
Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.