0

Плохо ли вызывать метод класса как метод экземпляра?

25

Заголовок: Правильно ли использовать методы класса без явного обращения к классу в Python?

Я столкнулся с вопросом, касающимся использования методов класса в Python. Вот пример кода, который у меня есть:

class C(object):
    @classmethod
    def f(cls, x):
       return x + x

Этот код работает следующим образом:

c = C()
print(c.f(2))  # Вывод: 4

Однако, возникает вопрос: является ли такой подход плохой практикой? Должен ли я вызывать метод так:

C.f(2)

или же так:

c.__class__.f(2)

Я понимаю, что это имеет смысл только в тех случаях, когда метод f не взаимодействует с self/cls, ожидая, что это будет класс.

Какой из этих вариантов считается более корректным и соответствует принципам хорошего стиля программирования в Python?

5 ответ(ов)

0

Если вас тянет вызвать метод класса из экземпляра, вероятно, вам не нужен метод класса.

В приведенном вами примере статический метод будет более подходящим именно из-за последнего замечания (отсутствие взаимодействия с self/cls).

class C(object):
    @staticmethod
    def f(x):
       return x + x

Таким образом, "правильный подход" здесь позволяет делать как

c = C()
c.f(2)

так и

C.f(2)
0

Я не припоминаю случаев использования класса-метода из вне, но, безусловно, нормально, если метод экземпляра вызывает класс-метод на себе (например, self.foo(), где foo — это класс-метод). Это гарантирует, что наследование работает как ожидается, и вызов .foo() произойдет в правильном подклассе, а не в базовом классе.

0

Это в основном просто сбивает с толку. Если бы я использовал ваш класс и увидел это, у меня бы возникли сомнения по поводу других «сюрпризов», которые могут скрываться внутри. Это выглядит как плохой дизайн.

Есть ли причина, по которой это реализовано не как статический метод?

0

C.f() более понятен, чем c_instance.f(), а c_instance.__class__.f() выглядит просто ужасно. Поскольку ясность и красота являются очень важными характеристиками в Python-сообществе, я бы сказал, что C.f() — это наилучший вариант.

Есть ли у вас какие-то конкретные причины, по которым вы хотите вызывать метод именно так или иначе?

0

В вашем коде действительно присутствует интересный механизм взаимодействия между обычными методами и методами класса. Давайте по шагам рассмотрим, как это работает, и почему это не вызывает ошибок в Python 3.6.

Вы создали класс A с обычным методом a, который вызывает два метода класса b и c. Это совершенно допустимо, поскольку методы класса имеют доступ к классу через аргумент cls, даже если они вызываются из обычного метода экземпляра.

Вот краткая разбивка, что происходит при выполнении вашего кода:

  1. Создается экземпляр класса A под именем b.
  2. Вызывается метод a с аргументом 3.
  3. Внутри метода a выполняется вывод print, который выводит информацию о текущем экземпляре и переданном числе.
  4. Затем вызывается метод класса b, который, как видно, соответствует синтаксису, позволяющему ему действовать независимо от конкретного экземпляра класса.
  5. В методе b также происходит вывод информации, и здесь используется переданное число, увеличенное на единицу.
  6. Метод b затем вызывает метод класса c, передавая число, которое будет умножено на 2.

В итоге вы видите, что, несмотря на то что метод b и c являются методами класса, они вызываются из обычного метода экземпляра, и это работает без каких-либо ошибок или исключений.

Таким образом, код деликатно подчеркивает гибкость Python, где обычные методы экземпляра могут взаимодействовать с методами класса, сохраняя при этом весь функционал.

Если вам нужно больше разъяснений или у вас есть другие вопросы, пожалуйста, дайте знать!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь