[Python] Можем ли мы вызвать пользовательский метод экземпляра внутри функции @classmethod?
Вопрос от новичка, я пытаюсь вызвать метод внутри метода с декоратором @classmethod, есть идеи, как этого добиться? Например у меня есть:
class A():
def B(self):
#do something
return something
@classmethod
def C(cls):
#do something
x = B() #call B method
return None
У меня есть ошибка:
NameError: global name 'B' is not defined
Могу ли я вызвать B или определить B как метод класса?
3 ответа
Проблема здесь не в том, что ваша функция "определена пользователем", проблема в том, что "x=B()" не вызывает метод с именем "B" внутри вашего класса, он вызывает метод с именем "B" в глобальное пространство имен.
Чтобы проиллюстрировать, что происходит, посмотрите на этот код:
B="1"
class A():
B="2"
def myfunc(cls):
print B
a = A()
a.myfunc()
Если вы запустите это, вы увидите, что вывод 1
,
Если вы измените print
заявление к print A.B
ты получишь 2
,
В вашем случае вам нужно позвонить A.B()
а не просто B()
Однако, как уже отмечали другие, B()
это метод экземпляра. Ожидается, что первый передаваемый параметр будет экземпляром класса. В зависимости от того, что делает B, вероятно, у вас будут проблемы, вызванные тем, что у вас нет экземпляра для его передачи. Вы можете обойти это различными способами, передав ему какой-то другой объект (например, сам класс) или создав новый объект для передачи; но мне кажется, что если C() нужно вызвать метод экземпляра, C() должен быть сам метод экземпляра.
Разница между методами класса и экземпляра говорит о разнице между методами класса и экземпляра.
Методы класса - это методы, которым не нужны данные экземпляра. Если B нужны данные экземпляра, как подразумевается с помощью self
тогда A не должен быть методом класса. Если B не нужны данные экземпляра, вы можете определить его как метод класса и вызвать его с помощью cls.B().
Чтобы сделать это, вам нужно сделать что-то вроде этого:
class A():
def B(self):
#do something (with self! so this requires A to be instantiated!)
return something
@classmethod
def C(cls):
#do something
return cls().B() #instantiate class, call B method, and return results