Próbuję zaimplementować przeciążanie metod w Pythonie:
class A:
def stackoverflow(self):
print 'first method'
def stackoverflow(self, i):
print 'second method', i
ob=A()
ob.stackoverflow(2)
ale wynik jest second method 2
; podobnie:
class A:
def stackoverflow(self):
print 'first method'
def stackoverflow(self, i):
print 'second method', i
ob=A()
ob.stackoverflow()
daje
Traceback (most recent call last):
File "my.py", line 9, in <module>
ob.stackoverflow()
TypeError: stackoverflow() takes exactly 2 arguments (1 given)
Jak to działa?
python
class
overloading
user1335578
źródło
źródło
Odpowiedzi:
Jest to przeciążenie metody, a nie przesłanianie metody . A w Pythonie robisz to wszystko w jednej funkcji:
Nie możesz mieć dwóch metod o tej samej nazwie w Pythonie - i nie musisz.
Zobacz sekcję Domyślne wartości argumentów samouczka języka Python. Zobacz „Najmniej zdziwienia” i Argument zmiennego domniemania, aby znaleźć typowy błąd, którego należy unikać.
Edycja : zobacz PEP 443, aby uzyskać informacje o nowych funkcjach ogólnych pojedynczego wysyłania w Pythonie 3.4.
źródło
Możesz także użyć pythonlangutil :
źródło
W Pythonie nie robisz rzeczy w ten sposób. Kiedy ludzie robią to w językach takich jak Java, zazwyczaj chcą mieć wartość domyślną (jeśli tego nie robią, zazwyczaj chcą metody o innej nazwie). Tak więc w Pythonie możesz mieć wartości domyślne .
Jak widać, to można to wykorzystać do uruchomienia osobnego zachowanie, a nie tylko o wartości domyślnej.
źródło
None
jest przydatne, gdy chcesz zmienić domyślną wartość. Oddzielne zachowanie powinno znajdować się w osobnych funkcjach.None
może być również przydatna jako prawdziwa wartość domyślna.Nie możesz, nigdy nie musisz i naprawdę nie chcesz.
W Pythonie wszystko jest obiektem. Klasy są rzeczami, więc są przedmiotami. Tak samo jak metody.
Istnieje obiekt o nazwie,
A
który jest klasą. Posiada atrybut o nazwiestackoverflow
. Może mieć tylko jeden taki atrybut.Kiedy piszesz
def stackoverflow(...): ...
, dzieje się tak, że tworzysz obiekt, który jest metodą i przypisujesz go dostackoverflow
atrybutuA
. Jeśli napiszesz dwie definicje, druga zastąpi pierwszą, tak jak zawsze zachowuje się przypisanie.Ponadto nie chcesz pisać kodu, który wykonuje dzikie czynności, do których czasami używa się przeciążenia. Nie tak działa język.
Zamiast próbować zdefiniować osobną funkcję dla każdego typu rzeczy, które możesz otrzymać (co nie ma sensu, ponieważ i tak nie określasz typów parametrów funkcji), przestań się martwić, czym są rzeczy i zacznij myśleć o tym, co mogą zrobić .
Nie tylko nie możesz napisać oddzielnego, aby obsłużyć krotkę w porównaniu z listą, ale także nie chcesz lub nie musisz tego robić .
Wszystko, co musisz zrobić, to wykorzystać fakt, że oba są na przykład iterowalne (czyli możesz pisać
for element in container:
). (Fakt, że nie są one bezpośrednio powiązane dziedziczeniem, nie ma znaczenia).źródło
@overload
dekoratora, powiedziałbym, że „naprawdę nie chcę” jest w najlepszym przypadku dyskusyjna. Od PEP-3124, „… jest to obecnie powszechny wzorzec dla kodu Pythona do sprawdzania typów odbieranych argumentów…„ oczywistym sposobem ”na to jest kontrola typu, ale jest to kruche i zamknięte dla rozszerzenie ... "Wygląda więc na to, że wystarczająco dużo ludzi tego chciało, że stało się częścią Pythona.@overload
jest przeznaczony tylko do pisania.Podczas gdy @agf miał rację z odpowiedzią w przeszłości, teraz z PEP-3124 , otrzymaliśmy nasz cukier składniowy. Zobacz dokumentację dotyczącą pisania, aby uzyskać szczegółowe informacje na temat
@overload
dekoratora, ale zwróć uwagę, że to tak naprawdę jest tylko cukier składniowy i IMHO to wszystko, o co ludzie się kłócili od tego czasu. Osobiście zgadzam się, że o wiele funkcji z różnych podpisów czyni go bardziej czytelnym następnie posiadające jedną funkcję z 20+ argumentów wszystko ustawione na wartość domyślną (None
przez większość czasu), a następnie konieczności pobawić wokół używając nieskończoneif
,elif
,else
łańcuchy, aby dowiedzieć się, co wywołujący w rzeczywistości chce, aby nasza funkcja działała z podanym zestawem argumentów. Było to dawno spóźnione po Python Zeni prawdopodobnie również
Prosto z oficjalnej dokumentacji Pythona, do której link znajduje się powyżej:
źródło
@overload
funkcje ed nie powinny mieć żadnej rzeczywistej implementacji. Nie jest to oczywiste z przykładu w dokumentacji Pythona.Piszę swoją odpowiedź w Pythonie 3.2.1.
Jak to działa:
overload
pobiera dowolną liczbę wywołań i przechowuje je w krotcefunctions
, a następnie zwraca lambda.functions[number_of_unnamed_args_passed]
wywołanej funkcji z argumentami przekazanymi do lambdy.Stosowanie:
źródło
Myślę, że słowo, którego szukasz, to „przeciążenie”. W Pythonie nie ma przeciążenia metod. Możesz jednak użyć domyślnych argumentów w następujący sposób.
Kiedy przekażesz mu argument, będzie on postępował zgodnie z logiką pierwszego warunku i wykona pierwszą instrukcję print. Gdy nie przekażesz mu żadnych argumentów, przejdzie do
else
warunku i wykona drugą instrukcję print.źródło
Piszę swoją odpowiedź w Pythonie 2.7:
W Pythonie przeciążanie metod nie jest możliwe; jeśli naprawdę chcesz uzyskać dostęp do tej samej funkcji z różnymi funkcjami, sugeruję, aby przejść do nadpisywania metody.
źródło
W Pythonie przeciążenie nie jest pojęciem stosowanym. Jeśli jednak próbujesz utworzyć przypadek, w którym na przykład chcesz, aby jeden inicjator był wykonywany, jeśli przekazano argument typu
foo
i inny inicjator dla argumentu typubar
, ponieważ wszystko w Pythonie jest obsługiwane jako obiekt, możesz sprawdzić nazwę typu klasy przekazanego obiektu i na tej podstawie napisz obsługę warunkową.W razie potrzeby tę koncepcję można zastosować do wielu różnych scenariuszy za pomocą różnych metod.
źródło
W Pythonie zrobiłbyś to z domyślnym argumentem.
źródło
Właśnie znalazłem ten https://github.com/bintoro/overloading.py dla każdego, kto może być zainteresowany.
Z pliku readme połączonego repozytorium:
źródło
Python nie obsługuje przeciążania metod, takich jak Java czy C ++. Możemy przeciążać metody, ale możemy używać tylko najnowszej zdefiniowanej metody.
Musimy podać opcjonalne argumenty lub * args, aby zapewnić inną liczbę argumentów podczas wywoływania.
Dzięki uprzejmości https://www.geeksforgeeks.org/python-method-overloading/
źródło
Python 3.x zawiera standardową bibliotekę typowania, która pozwala na przeciążanie metody przy użyciu dekoratora @overload. Niestety, ma to na celu uczynienie kodu bardziej czytelnym, ponieważ po metodzie dekorowanej @overload musi następować metoda bez dekoracji, która obsługuje różne argumenty. Więcej można znaleźć tutaj , ale na przykład:
źródło
W pliku MathMethod.py
W pliku Main.py
Możemy przeciążyć metodę używając multipledispatch
źródło
Python dodał dekorator @overload z PEP-3124 aby zapewnić cukier syntaktyczny do przeciążania poprzez kontrolę typu - zamiast po prostu pracować z nadpisywaniem.
Przykład kodu w przypadku przeciążania przez @overload z PEP-3124
jest przekształcany przez dekorator @ overload na:
źródło