Fungsi panggilan python di dalam kelas

242

Saya memiliki kode ini yang menghitung jarak antara dua koordinat. Kedua fungsi keduanya berada dalam kelas yang sama.

Namun bagaimana cara memanggil fungsi distToPointdalam fungsi 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)
        ...
Steven
sumber
41
coba: self.distToPoint (p)
momeara
Bagaimana jika isNear dan distToPoint mengambil argumen yang berbeda. Lalu Bagaimana kita memanggil distToPoint yang ada di dalam kelas? Siapapun dapat menjelaskannya untuk saya.
Raghavendra Gupta

Jawaban:

394

Karena ini adalah fungsi anggota, panggil itu sebagai fungsi anggota pada contoh self,.

def isNear(self, p):
    self.distToPoint(p)
    ...
Jeff Mercado
sumber
2
Tapi hati-hati self.foo () akan menggunakan urutan resolusi metode yang mungkin menyelesaikan fungsi di kelas yang berbeda.
Francis Davey
Apa yang terjadi jika kita tidak menggunakan diri sendiri? dan langsung hubungi distToPoint (p)?
Marlon Abeykoon
3
@Marlon Abeykoon argumen "diri" akan hilang
Pitipaty
1
Bagaimana jika isNear dan distToPoint mengambil argumen yang berbeda. Lalu Bagaimana kita memanggil distToPoint yang ada di dalam kelas? Siapapun dapat menjelaskannya untuk saya.
Raghavendra Gupta
46

Yang tidak bekerja karena distToPointdi dalam kelas Anda, sehingga Anda perlu untuk awalan dengan classname jika Anda ingin menyebutnya, seperti ini: classname.distToPoint(self, p). Anda seharusnya tidak melakukannya seperti itu. Cara yang lebih baik untuk melakukannya adalah untuk merujuk pada metode langsung melalui contoh kelas (yang merupakan argumen pertama dari metode kelas), seperti: self.distToPoint(p).

Aleksi Torhamo
sumber
@Aleski. Jika ini adalah metode generik (umum untuk semua instance dan tanpa variabel instan contoh apa pun yang dirujuk dalam metode ini), dapatkah Anda menjelaskan mengapa orang tidak boleh menggunakan classname.distToPoint (self, p)?
Yugmorf
2
@ Yugmorf: Hanya ada satu situasi di mana orang harus menggunakan classname.distToPoint(self, p): ketika Anda mendefinisikan subclass yang menimpa distToPoint, tetapi perlu memanggil yang asli. Jika Anda mencoba memanggil self.distToPoint(p)seperti biasa dalam kasus itu, Anda akan berakhir memanggil metode yang baru saja Anda tetapkan, dan masuk ke rekursi tak terbatas. Jika tidak di dalam kelas, hanya ada satu situasi di mana Anda akan menggunakan classname.distToPoint(obj, p)alih-alih obj.distToPoint(p): jika obj mungkin merupakan turunan dari subkelas, tetapi Anda perlu memanggil yang asli yang distToPointdidefinisikan (lanjutan)
Aleksi Torhamo
1
di classnamebukannya versi yang ditimpa dalam subclass - tetapi perhatikan bahwa ini sangat hacky dan tidak boleh dilakukan secara umum tanpa alasan yang sangat bagus. Perhatikan bahwa Anda memecah polimorfisme subtipe ketika Anda memanggil metode secara eksplisit melalui kelas (dalam kedua contoh di atas, Anda secara khusus ingin melakukan itu). Jadi singkatnya: Anda hanya perlu memanggil metode secara eksplisit melalui kelas ketika Anda perlu menghindari polimorfisme subtipe untuk beberapa alasan [baik]. Jika metode ini belum ditimpa, kedua cara itu sama, tetapi self.distToPoint(p)lebih pendek dan lebih mudah dibaca, (lanjutan)
Aleksi Torhamo
jadi Anda harus tetap menggunakannya. Sekarang, dapatkan spesifik pertanyaan Anda: jika metode Anda tidak menggunakan variabel contoh apa pun, mungkin itu seharusnya metode kelas? Anda membuatnya dengan menambahkan @classmethodsebelum metode, dan setelah itu Anda tidak akan mendapatkan instance ( self) sebagai argumen pertama lagi - sebagai gantinya Anda mendapatkan kelas, jadi Anda harus memberi nama argumen pertama misalnya. clssebagai gantinya. Setelah itu, Anda dapat memanggil metode kelas baik suka obj.distToPoint(p)atau classname.distToPoint(p)(perhatikan kurangnya obj). Anda mungkin masih harus menggunakan (lanjutan)
Aleksi Torhamo
obj.distToPoint(p), meskipun, jika Anda hanya memiliki contoh yang relevan di tangan Anda, kecuali - lagi - Anda memiliki beberapa alasan [baik] untuk menghindari polimorfisme subtipe, karena metode kelas bisa saja ditimpa dalam subkelas juga, secara umum. Tentu saja, jika Anda tidak memiliki relevan contoh tersedia, Anda harus dengan segala cara memanggil classmethod langsung melalui kelas.
Aleksi Torhamo