Функція виклику Python у класі


242

У мене є цей код, який обчислює відстань між двома координатами. Обидві функції виконуються в одному класі.

Однак як мені викликати функцію distToPointу функції 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
спробуйте: self.distToPoint (p)
momeara

Що робити, якщо IsNear та distToPoint беруть різні аргументи. Тоді Як ми можемо викликати distToPoint, який знаходиться всередині класу? Будь-хто може мені це пояснити.
Рагхавендра Гупта

Відповіді:


394

Так як ці функції - члени, назвемо його в якості опції члена на примірнику, self.

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

2
Але будьте обережні, self.foo () використовуватиме порядок роздільної здатності методу, який може вирішити функцію в іншому класі.
Френсіс Дейві

Що станеться, якщо ми не використовуємо себе? і безпосередньо викликати distToPoint (p)?
Марлон Абейкон

3
@Marlon Abeykoon аргумент "Я" відсутній
Pitipaty

1
Що робити, якщо IsNear та distToPoint беруть різні аргументи. Тоді Як ми можемо викликати distToPoint, який знаходиться всередині класу? Будь-хто може мені це пояснити.
Рагхавендра Гупта

46

Це не працює , тому що distToPointзнаходиться всередині вашого класу, так що вам потрібно префікс з ім'ям класу , якщо ви хочете , щоб звернутися до нього, як це: classname.distToPoint(self, p). Ти не повинен робити це так. Кращий спосіб зробити це полягає в посилання до методу безпосередньо через екземпляр класу (який є першим аргументом методу класу), наприклад , так: self.distToPoint(p).


@Aleski. Якщо це загальний метод (загальний для всіх екземплярів і без будь-яких конкретних змінних екземплярів, на які посилається метод), чи можете ви пояснити, чому не слід використовувати classname.distToPoint (self, p)?
Югморф

2
@Yugmorf: Є лише одна ситуація, коли слід використовувати classname.distToPoint(self, p): коли ви визначаєте підклас, який переосмислює distToPoint, але потрібно викликати оригінал. Якщо ви спробували self.distToPoint(p)в такому випадку зателефонувати як звичайний, ви в кінцевому підсумку зателефонуєте до методу, який ви просто визначаєте, і потрапите в нескінченну рекурсію. Якщо ви не знаходитесь у класі, ви також можете використовувати лише одну ситуацію, якщо ви використовуєте classname.distToPoint(obj, p)замість obj.distToPoint(p): якщо obj може бути екземпляром підкласу, але вам потрібно зателефонувати до distToPointвизначеного оригіналу (продовження)
Aleksi Torhamo

1
в classnameзамість перевантаженої версії в підкласі - але врахуйте , що це дуже Hacky і не повинно бути зроблено взагалі без дуже поважної причини. Зауважте, що ви порушуєте поліморфізм підтипу, коли викликуєте метод явно через клас (в обох наведених вище прикладах ви спеціально хочете це зробити). Отже, коротко: ви повинні викликати метод явно через клас, коли вам потрібно обходити поліморфізм підтипу з якоїсь [доброї] причини. Якщо метод не був відмінений, два способи рівні, але self.distToPoint(p)коротший і читабельніший (продовження)
Aleksi Torhamo

тож вам обов'язково все-таки слід користуватися. Тепер, переходимо до специфіки вашого запитання: якщо ваш метод не використовує змінних екземплярів, можливо, це повинен бути замість нього класний метод? Ви робите це, додаючи @classmethodперед методом, і після цього більше не будете отримувати екземпляр ( self) як перший аргумент - замість цього ви отримаєте клас, тому слід назвати перший аргумент, наприклад. clsзамість цього. Після цього ви можете викликати classmethod або як ( obj.distToPoint(p)або classname.distToPoint(p)відзначити відсутність obj). Ви все ще повинні, мабуть, використовувати (продовження)
Алексі Торхамо

obj.distToPoint(p), хоча, якщо у вас просто є відповідний екземпляр на руках, якщо, знову ж таки, - у вас є [хороші] причини для того, щоб обійти поліморфізм підтипу, оскільки класний метод також міг бути замінений в підкласі загалом. Звичайно, якщо у вас немає відповідного екземпляра, вам слід обов'язково викликати classmethod безпосередньо через клас.
Алексі Торхамо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.