Wpis z mikrobloga

Mirki, jaka jest różnica między decorator, a context manager w Pythonie?
To są dwie różne struktury, ale w gruncie rzeczy pozwalające na uzyskanie tego samego efektu, czyli zamknięcie jakiegoś działania/funkcji/fragmentu kodu wewnątrz innej czynności. Czyli w sumie dzięki nim dostajemy dość uniwersalny wrapper.
Odnoszę wrażenie, że w 100% przypadków możemy używać tych konstruktów zamiennie, ale gdyby tak faktycznie było, to nikt by tego nie implementował. Jest między nimi jakaś zasadnicza różnica? Kiedy je stosować?

#python #programowanie
  • 11
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@grajlord: Ich przeznaczenie jest inne. Ogólnie to CM służy najczęściej do tego, żeby bezpiecznie zamknąć zasoby, nawet w przypadku wystąpienia wyjątku, bez powtarzania bloków try/except/finally - coś trochę podobnie jak try-with-resource w Javie.
Natomiast dekoratory służą faktycznie do wzbogacenia funkcjonalności, coś na wzór adnotacji w Javie (chociaż zasada ich działania jest diametralnie inna).
  • Odpowiedz
@grajlord: Z definicji to to samo. Co do zastosowania:

Context managery sa najczesciej uzywane do resource handling (zarzadzania zasobami?). Zasadniczo jezeli musisz wywolac na jakims obiekcie metode 'close' po zakonczeniu akcji to powinno to byc zrobione z wykorzystaniem context managera. Z innych context managerow masz jeszcze Lock z threading, tez warty obczajenia.

Swoja droga sa one tak popularne, ze masz im poswiecony caly modul contextlib. Od pythona 3.2 (?) mozesz
  • Odpowiedz
Ich przeznaczenie jest inne

Context managery sa najczesciej uzywane

@dog_meat: @zarev: Ale to chyba tylko wynika z ogólnie przyjętego schematu/przyzwyczajeń, nie?

Ja mam raczej wrażenie, że kontekst managera używamy jeżeli mamy dłuższą funkcję i jej fragment zamykamy w managerze. Natomiast dekoratora użyjemy do zamknięcia całej zawartości jakiejś funkcji. Przez co ostatecznie nie zależy to od wykonywanego przez nas działania, a od tego jak zorganizowaliśmy swój kod i jak
  • Odpowiedz
@grajlord: context menager jak sama nazwa sugeruje służy do zarządzania kontekstem, otwierasz i zamykasz strumień/plik i w trakcie chcesz coś porobić, dobrym przykładem jest djangowski transaction.atomic -> korzystając z tego kontekstu jeśli pojawi się jakiś błąd to automatycznie jest robiony rollback w bazie danych.

decorator to natomiast wzorzec projektowy który pozwala ci rozszerzać możliwości funkcji/klasy bez jej bezpośredniej modyfikacji.

nie widzę związku między tymi rzeczami

składniowo w pythonie są podobne,
  • Odpowiedz
@grajlord: w kontekst menadżerze masz 3 stany - otwarcie kontekstu, sam kontekst i zamknięcie kontekstu. to jest cała ideologia.

oczywiście możesz napisać decorator który będzie się zachowywał jak kontext menegar, ale nie powinieneś i takie coś nie powinno też przejść w code review. python jest po prostu syfiastym językiem wbrew pozorom i nie warto się uczyć na nim programować bo za dużo pozwala i robi tylko mętlik w głowie. w
  • Odpowiedz
nie widzę związku między tymi rzeczami

@gryzon_c: No ale skoro równie dobrze mógłbym sobie otwierać/zamykać plik dekoratorem, albo rozszerzyć funkcję wywołując ją z obrębu context managera, to jakiś związek jest?
Na razie z tego co widzę główna różnica jest taka, że context manager zawsze działa na zasadzie generatora.
  • Odpowiedz
@grajlord: plus oczywiście kontruktor w pythonie nie zachowuje się jak klasyczny konstruktor (co jest oczywiste biorąc pod uwagę, ze w pythonie nie ma prawdziwych klas - są tylko obiekty zwracające kolejne obiekty) więc jest też inicjalizer który udaje konstruktor by laicy myśleli, że to konstruktor
  • Odpowiedz
@grajlord: więc podsumowując python składniowo strasznie kłamie - to co się dzieje naprawdę jest sprzeczne z tym co ci się wydaje, że się dzieje.

coś jak syntax klas w es6 gdzie w js są dalej prototypy, ale dużo ludzi jest uradowanych bo można definiować klasy - w rzeczywistości dalej nie można
  • Odpowiedz