Função de chamada Python dentro da classe


242

Eu tenho esse código que calcula a distância entre duas coordenadas. As duas funções estão dentro da mesma classe.

No entanto, como chamo a função distToPointna função 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
Tente: self.distToPoint (p)
momeara

E se isNear e distToPoint estiverem usando argumentos diferentes. Então, como podemos chamar distToPoint, que está dentro da classe? Qualquer um pode explicar isso para mim, por favor.
Raghavendra Gupta

Respostas:


394

Uma vez que estas são funções de membro, chamá-lo como uma função membro na instância, self.

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

2
Mas tenha cuidado self.foo () usará a ordem de resolução do método que pode resolver uma função em uma classe diferente.
Francis Davey

O que acontece se não usarmos o eu? e chamar diretamente distToPoint (p)?
Marlon Abeykoon 16/08/16

3
@Marlon Abeykoon o "eu" argumento vai estar ausente
Pitipaty

1
E se isNear e distToPoint estiverem usando argumentos diferentes. Então, como podemos chamar distToPoint, que está dentro da classe? Qualquer um pode explicar isso para mim, por favor.
Raghavendra Gupta

46

Isso não funciona porque distToPointestá dentro de sua classe, então você precisa prefixo com o nome da classe, se você quiser se referir a ele, como este: classname.distToPoint(self, p). Você não deve fazer assim, no entanto. A melhor maneira do fazer é para referir o método directamente através da instância de classe (que é o primeiro argumento de um método de classe), assim: self.distToPoint(p).


@Aleski. Se for um método genérico (comum a todas as instâncias e sem nenhuma variável específica da instância mencionada no método), você poderia explicar por que não se deve usar classname.distToPoint (self, p)?
Yugmorf

2
@Yugmorf: Existe apenas uma situação em que se deve usar classname.distToPoint(self, p): quando você está definindo uma subclasse que substitui distToPoint, mas precisa chamar o original. Se você tentasse ligar self.distToPoint(p)normalmente, nesse caso, acabaria chamando o método que está definindo e entraria em uma recursão infinita. Se não estiver dentro de uma classe, também há apenas uma situação em que você usaria em classname.distToPoint(obj, p)vez de obj.distToPoint(p): se obj pode ser uma instância da subclasse, mas você precisa chamar o original distToPointdefinido (continuação)
Aleksi Torhamo

1
em classnamevez da versão substituída na subclasse - mas nota que isso é muito hacky e não deve ser feito, em geral, sem muito boa razão. Observe que você quebra o polimorfismo de subtipo ao chamar um método explicitamente por meio de uma classe (nos dois exemplos acima, você deseja fazer isso especificamente ). Então, resumindo: você só deve chamar um método explicitamente através de uma classe quando precisar contornar o polimorfismo de subtipo por algum [bom] motivo. Se o método não foi substituído, as duas maneiras são iguais, mas self.distToPoint(p)são mais curtas e mais legíveis, (continuação) #
Aleksi Torhamo 10/10

então você definitivamente ainda deve usá-lo. Agora, chegando às especificidades da sua pergunta: se o seu método não usa nenhuma variável de instância, talvez seja um método de classe? Você faz isso adicionando @classmethodantes do método e depois disso não terá mais uma instância ( self) como o primeiro argumento - em vez disso, obtém a classe, portanto, deve nomear o primeiro argumento, por exemplo. clsem vez de. Depois disso, você pode ligar para o classmethod quer como obj.distToPoint(p)ou classname.distToPoint(p)(note a falta de obj). Você provavelmente ainda deve usar (continuação) #
Aleksi Torhamo 10/10

obj.distToPoint(p)no entanto, se você tiver apenas uma instância relevante em suas mãos, a menos que - novamente - você tenha algum [bom] motivo para contornar o polimorfismo de subtipo, pois o método de classe também poderia ter sido substituído em uma subclasse em geral. Obviamente, se você não tem uma instância relevante disponível, deve chamar o método de classe diretamente por meio de uma classe.
Aleksi Torhamo 10/10
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.