Lambda czy metoda statyczna - kiedy co stosować?

0

Kiedy stosuje się lambdę a kiedy metodę statyczną?

0

Lambde tworzysz jak chcesz w dynamiczny sposob wykonstruowac funkcje. (dynamiczny w sensie run-timu a nie typow). EDIT: albo miec funkcje anonimowa bo uzywasz tego tylko lokalnie. (patrz map/filter/reduce)

Skad takie pytanie w ogole?

4

Z grubsza mówiąc nie należy stosować ani jednego ani drugiego. No, lambdy spotyka się częściej ale często można się bez nich obejść.

Lambdy mają swoje zastosowanie jako drobne funkcje anonimowe, ale mają swoje ograniczenia, takie jak konieczna jedna linijka, czy chociażby to, że nie można ich pickle'ować:

>>> import pickle
>>> pickle.dumps(lambda: None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7f9e7b21d550>: attribute lookup <lambda> on __main__ failed
>>> 
>>> def foo():
...     pass
... 
>>> pickle.dumps(foo)
b'\x80\x04\x95\x14\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x03foo\x94\x93\x94.'

Do tego bardzo często można się bez nich obejść. Standardowa biblioteka oferuje funkcje operator.itemgetter, operator.methodcaller i operator.attrgetter i inne, które często pozwalają zastąpić lambdy. Sztandarowym przykładem zastosowania jest typowe zadanie-test na rekrutację z Pythona - jak posortować listę słowników po danym kluczu...?

>>> l = [{'a': 12}, {'a': 2}, {'a': 100}, {'a': 8}]
>>> sorted(l, key=lambda d: d['a']) # lambda
[{'a': 2}, {'a': 8}, {'a': 12}, {'a': 100}]
>>>
>>> import operator
>>> sorted(l, key=operator.itemgetter('a')) # operator
[{'a': 2}, {'a': 8}, {'a': 12}, {'a': 100}]

Użycie operator będzie nieco szybsze i jest uważane przez wielu za bardziej "pytoniczne", choć musisz wykonać jeden ekstra import. Analogicznie lepiej używać list comprehension niż stosować map z lambdami

>>> l = [1, 2, 3, 4, 5]
>>> list(map(lambda x: x**3, l)) # tu jest lambda...
[1, 8, 27, 64, 125]
>>> [x**3 for x in l] # ..ale można się bez niej obejść
[1, 8, 27, 64, 125]

Czasem jednak bywa, że taka lambda po prostu bardziej pasuje. Przykładem jest funkcja, która przyjmuje jakiś callable jako argument. Wówczas przekazanie lambdy pozwala na łatwe wykonanie wskazanej operacji zamiast mozolnego definiowania osobnej funkcji. Przydają się również w konsoli interaktywnej, do szybkiego pisania, gdy nie chcemy, jak w kodzie produkcyjnym, pracowicie tworzyć odpowiednich funkcji pomocniczych. W każdym razie ich nadużywanie to trochę jednak code smell.

Metody statyczne nie są natomiast szczególnie użyteczne, ponieważ generalnie nic się nie zyskuje deklarując funkcją jako metodę statyczną - można po prostu zadeklarować ją jako normalną funkcję globalną. Metoda statyczna nie jest bowiem, w przeciwieństwie do metody zwykłej czy metody klas, powiązana odpowiednio z danym obiektem bądź typem. Równie dobrze może zatem egzystować w izolacji. W rezultacie spotyka się je raczej rzadko.

0
Spearhead napisał(a):

Metoda statyczna nie jest bowiem, w przeciwieństwie do metody zwykłej czy metody klas, powiązana odpowiednio z danym obiektem bądź typem. Równie dobrze może zatem egzystować w izolacji. W rezultacie spotyka się je raczej rzadko.

No właśnie -- w Pythonie nie widziałem definicji metody statycznej użytej sensownie (ale może mało widziałem :)) -- szczególnie, że Python bardzo ładnie wspiera moduły i zamiast metody statycznej raczej powinno się robić zwykłą funkcję na poziomie modułu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1