Sınıf içindeki Python çağrı fonksiyonu


242

İki koordinat arasındaki mesafeyi hesaplayan bu kodu var. İki işlevin ikisi de aynı sınıftadır.

Ancak nasıl işlev diyorsunuz distToPointişlevinde 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
deneyin: self.distToPoint (p)
momeara

İsNear ve distToPoint farklı argümanlar alıyorsa ne olur. O halde sınıfın içindeki distToPoint'i nasıl arayabiliriz? Bunu herkes bana açıklayabilir.
Raghavendra Gupta

Yanıtlar:


394

Bunlar üye işlevleri olduğundan, bunu örnek üzerinde üye işlevi olarak adlandırın self.

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

2
Ancak dikkatli olun self.foo () yöntemi, farklı bir sınıftaki bir işleve çözümlenebilecek yöntem çözümleme sırasını kullanır.
Francis Davey

Kendini kullanmazsak ne olur? ve doğrudan distToPoint (p) 'yi çağırınız.
Marlon Abeykoon

3
@Marlon Abeykoon "öz" argümanı eksik olacak
Pitipaty

1
İsNear ve distToPoint farklı argümanlar alıyorsa ne olur. O halde sınıfın içindeki distToPoint'i nasıl arayabiliriz? Bunu herkes bana açıklayabilir.
Raghavendra Gupta

46

Çünkü iş değil distToPointEğer böyle bu mesajı inceleyin isterseniz sınıfadı, öneki gerekir, böylece sınıfının içindeyse: classname.distToPoint(self, p). Yine de böyle yapmamalısın. Bunu yapmak için daha iyi bir yolu şöyle, (bir sınıf yönteminin ilk bağımsız değişken olan) sınıfı örneği doğrudan yönteme başvurmak için: self.distToPoint(p).


@Aleski. Bu genel bir yöntemse (tüm örnekler için ortaktır ve yöntemde belirtilen herhangi bir örneğe özgü değişken olmadan), neden classname.distToPoint (self, p) kullanılmaması gerektiğini açıklayabilir misiniz?
Yugmorf

2
@Yugmorf: Kullanılması gereken tek bir durum vardır classname.distToPoint(self, p): geçersiz kılan distToPoint, ancak orijinali çağırması gereken bir alt sınıf tanımlarken . Bu self.distToPoint(p)durumda normal gibi aramayı denediyseniz , sadece tanımladığınız yöntemi çağırır ve sonsuz bir özyinelemeye girersiniz. Bir sınıfın içinde değilse, classname.distToPoint(obj, p)bunun yerine yalnızca tek bir durum kullanabilirsiniz obj.distToPoint(p): obj, alt sınıfın bir örneği olabilir, ancak distToPointtanımlanmış orijinali (devam)
Aleksi Torhamo 10'da 18

1
içinde classnameama bu çok hacky ve bir olmadan genel olarak yapılması gerektiğini not - yerine geçersiz kılınan alt sınıfta versiyonunun çok iyi bir nedenle. Bir yöntemi bir sınıf aracılığıyla açıkça çağırdığınızda alt tür polimorfizmini kırdığınızı unutmayın (yukarıdaki her iki örnekte de özellikle bunu yapmak istiyorsunuz ). Yani kısacası: Eğer açarken yalnızca bir sınıfın içinden açıkça bir yöntem çağırmalıdır gerek bazı [iyi] bir nedenle hileli alt tip polimorfizmi için. Yöntem geçersiz kılmamışsa, iki yol eşittir, ancak self.distToPoint(p)daha kısa ve daha okunabilir, (devam)
Aleksi Torhamo 10:30 '

bu yüzden kesinlikle kullanmalısınız. Şimdi, sorunuzun ayrıntılarına ulaşmak için: yönteminiz herhangi bir örnek değişkeni kullanmıyorsa, bunun yerine belki de bir sınıf yöntemi olmalıdır? Bunları @classmethodyöntemden önce ekleyerek yaparsınız ve bundan sonra selfilk argüman olarak artık bir example ( ) elde edemezsiniz - bunun yerine sınıfı alırsınız, bu nedenle ilk argümanı adlandırmalısınız. clsyerine. Bundan sonra, sınıf yöntemini ya gibi obj.distToPoint(p)ya da classname.distToPoint(p)(eksikliğine dikkat edin obj) çağırabilirsiniz . Sen olmalıdır hala muhtemelen kullanmak (devam)
Aleksi Torhamo

obj.distToPoint(p)Bununla birlikte, eğer elinizde sadece ilgili bir örneğiniz varsa, - yine - alt tür polimorfizmini atlatmak için [iyi] bir nedeniniz yoksa, sınıf yöntemi genel olarak bir alt sınıfta da geçersiz kılınmış olabilir. Eğer bir yoksa Tabii ki, ilgili örnek mevcuttur, tüm yollarla bir çağırmalıdır classmethod bir sınıf üzerinden doğrudan.
Aleksi Torhamo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.