Saya memiliki kode ini yang menghitung jarak antara dua koordinat. Kedua fungsi keduanya berada dalam kelas yang sama.
Namun bagaimana cara memanggil fungsi distToPoint
dalam 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)
...
Jawaban:
Karena ini adalah fungsi anggota, panggil itu sebagai fungsi anggota pada contoh
self
,.sumber
Yang tidak bekerja karena
distToPoint
di 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)
.sumber
classname.distToPoint(self, p)
: ketika Anda mendefinisikan subclass yang menimpadistToPoint
, tetapi perlu memanggil yang asli. Jika Anda mencoba memanggilself.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 menggunakanclassname.distToPoint(obj, p)
alih-alihobj.distToPoint(p)
: jika obj mungkin merupakan turunan dari subkelas, tetapi Anda perlu memanggil yang asli yangdistToPoint
didefinisikan (lanjutan)classname
bukannya 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, tetapiself.distToPoint(p)
lebih pendek dan lebih mudah dibaca, (lanjutan)@classmethod
sebelum 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.cls
sebagai gantinya. Setelah itu, Anda dapat memanggil metode kelas baik sukaobj.distToPoint(p)
atauclassname.distToPoint(p)
(perhatikan kurangnyaobj
). Anda mungkin masih harus menggunakan (lanjutan)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.