programowaniePython Backend Developer

Czym są dekatory parametrów funkcji w Pythonie, do czego są stosowane i jak są realizowane?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Historia pytania

W Pythonie dekoratory stały się częścią języka od wersji 2.4, zapewniając możliwość modyfikowania zachowania funkcji i klas. Dekoratory dla parametrów funkcji to bardziej złożony wzorzec, który realizuje się ręcznie, ponieważ język nie ma bezpośredniego wsparcia syntaktycznego dla takich dekoratorów. Jednak za pomocą adnotacji i metaprogramowania można zrealizować ich funkcjonalność.

Problem

Zwykłe dekoratory wpływają na całą funkcję lub metodę. Czasami konieczne jest walidowanie, rejestrowanie lub zmienianie tylko poszczególnych parametrów funkcji na określonym poziomie abstrakcji. Na przykład, należy sprawdzić typ argumentu, przekształcić wartość parametru lub nałożyć ograniczenia na wejście.

Rozwiązanie

Dekoratory parametrów funkcji są tworzone jako metadane (np. przez adnotacje typów) i przetwarzane w zewnętrznym opakowującym dekoratorze. Istota wzorca polega na zachowaniu odpowiednich informacji o parametrach, a następnie dekorator "funkcjonalny" wykorzystuje je do przetwarzania wartości podczas wywoływania funkcji.

Przykład kodu:

import inspect from functools import wraps def positive_param(fn): """Adnotacja do obowiązkowej weryfikacji pozytywności argumentu.""" fn._positive = True return fn # Zewnętrzny pełnoprawny dekorator def validate_decorator(func): spec = inspect.getfullargspec(func) @wraps(func) def wrapper(*args, **kwargs): bound_args = inspect.signature(func).bind(*args, **kwargs) for name, value in bound_args.arguments.items(): param = func.__annotations__.get(name, None) if getattr(param, '_positive', False) and value <= 0: raise ValueError(f"Argument {name} musi być pozytywny") return func(*args, **kwargs) return wrapper @validate_decorator def deposit(amount: positive_param): print(f"Wpłacono {amount}") deposit(10) # OK deposit(-5) # ValueError

Kluczowe cechy:

  • Umożliwia walidowanie lub modyfikowanie poszczególnych parametrów funkcji.
  • Wymaga przemyślanej struktury dekoratorów i przetwarzania adnotacji.
  • Nie jest bezpośrednio wspierane przez składnię języka, trzeba to zrealizować ręcznie.

Pytania z podstępem.

Czym różnią się dekoratory parametrów od standardowych dekoratorów funkcji?

Standardowy dekorator owija całą funkcję, niezależnie od parametrów. Dekorator parametru koncentruje się na konkretnym argumencie i stosuje się tylko do niego, co wymaga niestandardowych technik przetwarzania i analizy sygnatury.

Czy dekoratory parametrów mogą być realizowane za pomocą składni @ w Pythonie, tak jak w TypeScript lub C#?

Nie, w Pythonie składnia dekoratorów za pomocą @ jest stosowana tylko do funkcji i klas, ale nie do poszczególnych parametrów funkcji. Dla parametrów używa się adnotacji, a następnie przetwarzania adnotacji podczas opakowywania funkcji.

Czy można automatycznie stosować dekoratory do parametrów argumentów funkcji bez wyraźnej adnotacji?

Nie, Python nie stosuje dekoratorów automatycznie do parametrów, ale można zrealizować własny mechanizm, na przykład przez niestandardową fabrykę dekoratorów, która analizuje sygnaturę funkcji i zastępuje wartości parametrów podczas wywołania.

Typowe błędy i antywzorce

  • Przechowywanie stanu walidacji wewnątrz obiektu adnotacji i nie inicjowanie unikalnego obiektu dla każdego parametru, co prowadzi do błędów ze globalnym stanem.
  • Mieszanie logiki dekoratora parametru i funkcji, nie oddzielając odpowiedzialności.
  • Oczekiwanie na wsparcie składni @ dla parametrów — tego nie ma.

Przykład z życia

Negatywny przypadek

Programista jest przekonany, że można używać @ na parametrze, jak w innych językach, i pisze:

def f(@validate_positive x): ...

Zalety:

  • Kod wygląda deklaratywnie, czytelnie.

Wady:

  • Taki kod wywołuje błąd składniowy w Pythonie.
  • Programista traci czas na szukanie błędu.

Pozytywny przypadek

Programista używa adnotacji i zewnętrznego dekoratora, jak w powyższym przykładzie, i przetwarza parametry przez sygnaturę i adnotacje:

Zalety:

  • Gwarantowana walidacja poprawności każdego parametru.
  • Elastyczny system walidacji można rozszerzyć zgodnie z dowolnymi zasadami biznesowymi.

Wady:

  • Nieoczywistość wzorca dla mniej doświadczonych kolegów.
  • Kod jest bardziej skomplikowany od standardowych dekoratorów.