Python pozwala na przypisanie funkcji predefiniowanego do klasy jako atrybut, takich jakPrzypisywanie funkcji jako atrybutów obiektu, a następnie wywoływanie bez domniemanego "ja" argumentu?
def fish_slap(fish):
# do something
class dance(object):
dance_move=fish_slap
Jednak jeśli spróbujemy mów
d=dance()
d.dance_move("Halibut")
otrzymujemy pojawia się następujący błąd
TypeError: fish_slap() takes exactly 1 arguement (2 given)
Python wydaje się to postrzegać jako metodę obiektową i podać domniemany argument "ja". Wystarczająco uczciwe wydaje się, że właśnie dowiedziałem się, że przypisanie funkcji jako atrybutu w ten sposób jest równoznaczne z definiowaniem funkcji bezpośrednio w klasie. Widzę, że jest to przydatna funkcja.
Jednak w tym przypadku nie jest to, czego chcę. W mojej aplikacji mam modele statystyczne zakodowane jako różne klasy, które również mają swoje własne "pociągowe" metody szkolenia parametrów modelu względem dostarczonych danych. W tym celu należy zastosować funkcję celu, która ma zminimalizować (lub zmaksymalizować) wartość potrzebnych do dostarczenia. Przykładową prostą funkcją celu jest np.
def RMSE(predicted,observed):
"Root mean squared error"
return sp.sqrt(sp.mean((predicted-observed)**2))
gdzie SciPy została zaimportowana jako sp. Te obiektywne funkcje są zdefiniowane w jednym pliku .py i są używane w całym moim kodzie i naturalnie istnieją jako samodzielne funkcje, a nie jako metody klasowe z domniemanym argumentem "ja".
Chcę móc ustawić żądaną funkcję celu jako atrybut tak, że każda późniejsza praca obiekt modelu nie korzysta z tej funkcji, na przykład
some_model=SomeModel(initial_parameter_values_guess)
some_model.objective_function = RMSE
some_model.train(training_data)
predictions_RMSE = some_model.predict()
some_mode.objective_function = MAE
predictions_MAE = some_model.predict()
W tym przykładzie wydaje mogę tylko przekazać Funkcja obiektywna jako argument do treningu, jednak w mojej aplikacji jest o wiele więcej do zrobienia i wydaje się, że bardziej sensownym jest móc ustawić/uzyskać funkcję celu zamiast powtarzać ją jako argument.
Istnieje wiele sposobów obejścia tego podstawowego zachowania, ale jakie jest najbardziej pittonowe podejście?
Należy zauważyć, że mój obecny kod jest zgodny z python2 i python3. Jeśli istnieją rozwiązania specyficzne dla wersji, proszę o wskazanie tego. Używam python2, aby móc używać matplotlib, ale staram się zapewnić, że kod jest zgodny z python3 niezależnie od tego modułu.
dlaczego nie po prostu zmieniasz 'def fish_slap (fish):' na 'def fish_slap (self, fish):'? – Blender
@Blender, patrz akapit po zdefiniowaniu RMSE. Funkcje te są już zdefiniowane i używane w wielu innych miejscach jako samodzielne funkcje bez argumentów "ja". – Bogdanovist