Mam ten kod, który oblicza odległość między dwiema współrzędnymi. Obie funkcje należą do tej samej klasy.
Jak jednak wywołać funkcję distToPoint
w funkcji isNear
?
class Coordinates:
def distToPoint(self, p):
"""
Use pythagoras to find distance
(a^2 = b^2 + c^2)
"""
...
def isNear(self, p):
distToPoint(self, p)
...
Odpowiedzi:
Ponieważ są to funkcje składowe, nazywają ją jako funkcję członka na przykład
self
.źródło
To nie działa, ponieważ
distToPoint
jest wewnątrz swojej klasie, więc trzeba poprzedzić go z nazwy klasy, jeśli chcesz odnieść się do niego tak:classname.distToPoint(self, p)
. Nie powinieneś tego jednak robić. Lepszym sposobem na to, aby odnieść się do sposobu bezpośrednio na przykład klasy (który jest pierwszym argumentem metody klasy), tak jak poniżej:self.distToPoint(p)
.źródło
classname.distToPoint(self, p)
: podczas definiowania podklasy, która zastępujedistToPoint
, ale musi wywołać oryginał. Jeśliself.distToPoint(p)
w takim przypadku spróbujesz zadzwonić normalnie, skończysz na wywołaniu metody, którą właśnie definiujesz, i uzyskasz nieskończoną rekurencję. Jeśli nie znajduje się w klasie, istnieje również tylko jedna sytuacja, w której powinieneś użyćclassname.distToPoint(obj, p)
zamiastobj.distToPoint(p)
: jeśli obj może być instancją podklasy, ale musisz wywołać pierwotniedistToPoint
zdefiniowaną (ciąg dalszy)classname
zamiast zastąpionej wersji podklasy - należy jednak pamiętać, że jest to bardzo hacky i nie powinny być wykonywane w ogóle bez bardzo dobrego powodu. Zauważ, że łamiesz polimorfizm podtypu, gdy wywołujesz metodę bezpośrednio przez klasę (w obu powyższych przykładach chcesz to zrobić). W skrócie: powinieneś wywoływać metodę jawnie poprzez klasę tylko wtedy, gdy musisz ominąć polimorfizm podtypu z jakiegoś [dobrego] powodu. Jeśli metoda nie została zastąpiona, dwa sposoby są równe, aleself.distToPoint(p)
są krótsze i bardziej czytelne, (ciąg dalszy)@classmethod
przed metodą, a potem nie otrzymasz już instancji (self
) jako pierwszego argumentu - zamiast tego dostajesz klasę, więc powinieneś nazwać pierwszy argument np.cls
zamiast. Następnie możesz wywołać metodę klasowąobj.distToPoint(p)
lub lubclassname.distToPoint(p)
(zauważ brakobj
). Prawdopodobnie powinieneś nadal używać (ciąg dalszy)obj.distToPoint(p)
, jeśli jednak masz odpowiednią instancję na rękach, chyba że - znowu - masz jakiś [dobry] powód, aby ominąć polimorfizm podtypu, ponieważ metoda klasowa mogłaby zostać w ogóle zastąpiona w podklasie. Oczywiście, jeśli nie masz odpowiedniego dostępnej instancji, powinieneś za wszelką cenę wywołać metodę klasy bezpośrednio przez klasę.