[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 
Другие вопросы по тегам