Fonction d'appel Python dans la classe

242

J'ai ce code qui calcule la distance entre deux coordonnées. Les deux fonctions sont toutes deux dans la même classe.

Cependant, comment appeler la fonction distToPointdans la fonction 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
la source
41
essayez: self.distToPoint (p)
momeara
Et si isNear et distToPoint prennent des arguments différents. Alors, comment pouvons-nous appeler distToPoint qui est à l'intérieur de la classe? N'importe qui peut m'expliquer cela s'il vous plaît.
Raghavendra Gupta

Réponses:

394

Étant donné que ces fonctions sont membres, appeler en fonction de membre de l'instance, self.

def isNear(self, p):
    self.distToPoint(p)
    ...
Jeff Mercado
la source
2
Mais attention, self.foo () utilisera l'ordre de résolution de la méthode qui pourrait se résoudre en fonction dans une classe différente.
Francis Davey
Que se passe-t-il si nous ne nous utilisons pas? et appeler directement distToPoint (p)?
Marlon Abeykoon
3
@Marlon Abeykoon l'argument "soi" manquera
Pitipaty
1
Et si isNear et distToPoint prennent des arguments différents. Alors, comment pouvons-nous appeler distToPoint qui est à l'intérieur de la classe? N'importe qui peut m'expliquer cela s'il vous plaît.
Raghavendra Gupta
46

Cela ne fonctionne pas parce que distToPointl'intérieur de votre classe, vous devez le préfixe avec le nom de classe si vous voulez y faire référence, comme ceci: classname.distToPoint(self, p). Mais vous ne devriez pas faire comme ça. Une meilleure façon de le faire est de se référer à la méthode directement par l'instance de classe (qui est le premier argument d'une méthode de classe), comme suit: self.distToPoint(p).

Aleksi Torhamo
la source
@Aleski. S'il s'agit d'une méthode générique (commune à toutes les instances et sans variable spécifique d'instance référencée dans la méthode), pourriez-vous expliquer pourquoi il ne faut pas utiliser classname.distToPoint (self, p)?
Yugmorf
2
@Yugmorf: Il n'y a qu'une seule situation à utiliser classname.distToPoint(self, p): lorsque vous définissez une sous-classe qui remplace distToPoint, mais doit appeler l'original. Si vous essayez d'appeler self.distToPoint(p)comme d'habitude dans ce cas, vous finirez par appeler la méthode que vous venez de définir, et vous entrerez dans une récursion infinie. Si ce n'est pas dans une classe, il n'y a qu'une seule situation où vous utiliseriez à la classname.distToPoint(obj, p)place de obj.distToPoint(p): si obj pourrait être une instance de la sous-classe, mais vous devez appeler l'original distToPointdéfini (suite)
Aleksi Torhamo
1
dans classnameau lieu de la version redéfinie dans la sous-classe - mais notez que c'est très hacky et ne devrait pas être fait en général sans une très bonne raison. Notez que vous cassez le polymorphisme de sous-type lorsque vous appelez une méthode explicitement via une classe (dans les deux exemples ci-dessus, vous voulez spécifiquement le faire). Donc, en bref: vous ne devez appeler une méthode explicitement via une classe que lorsque vous devez contourner le polymorphisme de sous-type pour une [bonne] raison. Si la méthode n'a pas été outrepassée, les deux façons sont égales, mais self.distToPoint(p)sont plus courtes et plus lisibles, (suite)
Aleksi Torhamo
vous devez donc toujours l'utiliser. Maintenant, passons aux détails de votre question: si votre méthode n'utilise aucune variable d'instance, peut-être devrait-elle plutôt être une méthode de classe? Vous faites cela en ajoutant @classmethodavant la méthode, et après cela, vous n'obtiendrez plus une instance ( self) comme premier argument - à la place, vous obtenez la classe, vous devez donc nommer le premier argument par exemple. clsau lieu. Après cela, vous pouvez appeler la méthode de classe comme obj.distToPoint(p)ou classname.distToPoint(p)(notez l'absence de obj). Vous devriez toujours utiliser (suite)
Aleksi Torhamo
obj.distToPoint(p), cependant, si vous n'avez qu'une instance pertinente entre les mains, à moins que - encore une fois - vous n'ayez une [bonne] raison de contourner le polymorphisme de sous-type, car la méthode de classe aurait également pu être remplacée dans une sous-classe, en général. Bien sûr, si vous ne disposez pas d'une instance pertinente disponible, vous devez absolument appeler une méthode de classe directement via une classe.
Aleksi Torhamo