Является ли плохая форма вызовом classmethod как метод из экземпляра?
Исх.
Если у меня есть что-то вроде этого:
class C(object):
@classmethod
def f(cls, x):
return x + x
Это будет работать:
c = C()
c.f(2)
4
Но эта плохая форма?
Должен ли я звонить только
C.f()
или
c.__class__.f()
Очевидно, что это имело бы смысл только в тех случаях, когда f не взаимодействует с self/cls, ожидая, что он будет классом.
?
Ответы
Ответ 1
Если у вас возникает соблазн вызвать метод класса из экземпляра, вам, вероятно, не нужен метод класса.
В примере, который вы дали статическому методу, было бы более подходящим именно из-за вашего последнего замечания (без взаимодействия с самим /cls ).
class C(object):
@staticmethod
def f(x):
return x + x
таким образом, это "хорошая форма", чтобы сделать как
c = C()
c.f(2)
и
C.f(2)
Ответ 2
Я не помню, чтобы использовать классный метод, подобный этому, вне класса, но, конечно, нормально, чтобы метод экземпляра вызывал метод класса сам по себе (например, self.foo()
, где foo
- метод класса). Это гарантирует, что наследование действует так, как ожидалось, и вызовет .foo()
в правом подклассе вместо базового класса.
Ответ 3
Это в основном просто запутывающий взгляд. Если бы я использовал ваш класс и увидел это, это заставило бы меня задаться вопросом, какие еще сюрпризы там, это просто выглядит плохой дизайн.
Есть ли причина, по которой это не просто статический метод?
Ответ 4
Если у вас есть экземпляр C уже, зачем вам f() быть методом класса? Это не только плохая форма, она обычно не нужна. Кто-то в сети говорит: "Это плохо, потому что создается впечатление, что используются некоторые переменные экземпляра в объекте, но это не так".
Хотя на странице 484 learning python отмечается, что вы можете вызвать метод в любом случае, и он будет точно таким же, пока вы передать тот же экземпляр в.
Ответ 5
C.f()
понятнее, чем c_instance.f()
, а c_instance.__class__.f()
просто уродлива. Поскольку ясность и красота являются очень любимыми характеристиками в сообществе python, я бы сказал, что C.f() - лучший маршрут.
Есть ли какая-то конкретная причина, по которой вы даже хотите назвать ее одним из других способов?