Funzione di chiamata Python all'interno della classe


242

Ho questo codice che calcola la distanza tra due coordinate. Le due funzioni sono entrambe all'interno della stessa classe.

Tuttavia, come posso chiamare la funzione distToPointnella funzione 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)
        ...

41
provare: self.distToPoint (p)
momeara

Che cosa succede se isNear e distToPoint stanno prendendo argomenti diversi. Quindi come possiamo chiamare distToPoint che è all'interno della classe? Chiunque può spiegarmelo, per favore.
Raghavendra Gupta,

Risposte:


394

Poiché questi sono funzioni membro, chiamare come una funzione membro sul esempio self.

def isNear(self, p):
    self.distToPoint(p)
    ...

2
Ma attenzione self.foo () utilizzerà l'ordine di risoluzione del metodo che potrebbe risolversi in una funzione in una classe diversa.
Francis Davey,

Cosa succede se non usiamo se stessi? e chiamare direttamente distToPoint (p)?
Marlon Abeykoon,

3
@Marlon Abeykoon mancherà l'argomento "sé"
Pitipaty,

1
Che cosa succede se isNear e distToPoint stanno prendendo argomenti diversi. Quindi come possiamo chiamare distToPoint che è all'interno della classe? Chiunque può spiegarmelo, per favore.
Raghavendra Gupta,

46

Questo non funziona perché distToPointè dentro la classe, quindi è necessario prefisso con il nome della classe, se si vuole fare riferimento ad esso, in questo modo: classname.distToPoint(self, p). Non dovresti farlo in quel modo, però. Un modo migliore per farlo è far riferimento al metodo direttamente tramite l'istanza di classe (che è il primo argomento di un metodo di classe), in questo modo: self.distToPoint(p).


@Aleski. Se si tratta di un metodo generico (comune a tutte le istanze e senza variabili specifiche dell'istanza a cui fa riferimento il metodo), potresti spiegare perché non dovresti usare classname.distToPoint (self, p)?
Yugmorf,

2
@Yugmorf: c'è solo una situazione in cui si dovrebbe usare classname.distToPoint(self, p): quando si definisce una sottoclasse che ha la precedenza distToPoint, ma deve chiamare l'originale. Se self.distToPoint(p)in quel caso provassi a chiamare come di consueto, finiresti per chiamare il metodo che stai solo definendo e ti ritrovi in ​​una ricorsione infinita. Se non all'interno di una classe, c'è anche solo una situazione in cui useresti classname.distToPoint(obj, p)invece obj.distToPoint(p): se obj potrebbe essere un'istanza della sottoclasse, ma devi chiamare l'originale distToPointdefinito (continua)
Aleksi Torhamo

1
nella classnameanziché la versione sottoposta a override nella sottoclasse - ma è da notare che questo è molto hacky e non dovrebbe essere fatto, in generale, senza una molto buona ragione. Si noti che si rompe il polimorfismo del sottotipo quando si chiama un metodo in modo esplicito attraverso una classe (in entrambi gli esempi sopra, si desidera specificatamente farlo). Così, in breve: si dovrebbe chiamare solo un metodo in modo esplicito attraverso una classe quando si ha bisogno di aggirare il polimorfismo sottotipo per qualche [buon] ragione. Se il metodo non è stato ignorato, i due modi sono uguali, ma self.distToPoint(p)è più breve e più leggibile, (continua)
Aleksi Torhamo,

quindi dovresti sicuramente usarlo ancora. Ora, arrivando ai dettagli della tua domanda: se il tuo metodo non usa alcuna variabile di istanza, forse dovrebbe essere un metodo di classe invece? Puoi crearli aggiungendo @classmethodprima del metodo, e successivamente non otterrai più un'istanza ( self) come primo argomento - invece otterrai la classe, quindi dovresti nominare il primo argomento ad es. clsanziché. Successivamente, puoi chiamare il metodo di classe come obj.distToPoint(p)o classname.distToPoint(p)(nota la mancanza di obj). Probabilmente dovresti comunque usare (continua)
Aleksi Torhamo,

obj.distToPoint(p), tuttavia, se hai solo un'istanza pertinente nelle tue mani, a meno che - ancora una volta - non abbia qualche [buona] ragione per eludere il polimorfismo dei sottotipi, dal momento che il metodo di classe avrebbe potuto essere scavalcato anche in una sottoclasse, in generale. Naturalmente, se non si dispone di un'istanza rilevante disponibile, è necessario chiamare un metodo di classe direttamente attraverso una classe.
Aleksi Torhamo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.