Почему в следующем коде последняя строка выполнения выдает ошибку?

Почему в следующем коде последняя строка выполнения дает ошибку? Разве оператор точки в x.bf() не должен передавать экземпляр 'x' функции bf (как x.af())?

class A:
    a = 6
    def af (self):
        return "Hello-People"

class B:
    b = 7
    def bf (self):
        return "Bye-People"

>>> x = A()
>>> b = B()
>>> x.bf = B.bf
>>> x.bf()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bf() missing 1 required positional argument: 'self'

person user3260901    schedule 16.12.2014    source источник


Ответы (1)


x.bf = B.bf - ваша ошибка, потому что B - это класс, а не экземпляр объекта.

Вы не можете назначить x.bf непосредственно классу. Вам нужно назначить x.bf экземпляру «b.bf» или правильно создать экземпляр класса.

т.е. Либо измените эту строку на:

# Where we instantiated class B and invoke bf via lazy loading (loading at the last possible minute)
x.bf = B().bf 

or

# Use the existing instance of B and call bf
x.bf = b.bf

Дополнительная информация:

  1. А и В ваши классы. Они ничего не делают, пока вы не создадите их экземпляр.
  2. x и b - ваши экземпляры объекта. x является экземпляром A, а b является экземпляром B
  3. Всякий раз, когда вы создаете экземпляр класса, вам необходимо соответствовать его подписи конструктора. В этом случае классы не требуют дополнительных параметров, кроме self. Однако self передается только в том случае, если класс вызывается через ();

    'x = A()' и 'b = B()' соответствуют этой подписи

    Ошибка, с которой вы столкнулись, в основном связана с тем, что python сообщает вам, что вы вызвали что-то, функцию или класс, не передав требуемую переменную.

person rurouni88    schedule 16.12.2014
comment
Не могли бы вы объяснить, почему это происходит более подробно. - person user3260901; 16.12.2014
comment
Но в последней строке x.bf() x — это переменная экземпляра. Так не должен ли он передать себя bf ? - person user3260901; 16.12.2014
comment
Правильный. Последняя строка может быть записана как x.bf или x.bf(). Я решил оставить его как x.bf(), потому что личное предпочтение состоит в том, чтобы всегда вызывать функцию и указывать, что ее сигнатура функции выполняется. x.bf() говорит мне, что я вызываю bf() для объекта x, и ему не нужны дополнительные параметры. - person rurouni88; 16.12.2014
comment
Хорошо. Я немного смущен. Что связывает B.bf с x.bf (во второй последней строке)? Если это определение функции bf из B, то не будет ли оно передавать x в качестве аргумента self для x.bf(), таким образом, не выдавая ошибку? - person user3260901; 16.12.2014
comment
x.bf не имеет ничего общего с этим. x.bf — это просто переменная объекта x. Оператор (ы) x.bf = B().bf или x.bf() = b.bf в основном говорит python присвоить ВОЗВРАЩЕННОЕ значение B().bf или b.bf для x.bf. Имеет ли это смысл? Ваша исходная ошибка возникла, потому что вы не можете вызвать B.bf. Вам нужно создать экземпляр B(), а затем вызвать bf, таким образом, решение B().bf. - person rurouni88; 16.12.2014