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.