Unbound method f() должен быть вызван с экземпляром fibo_ в качестве первого аргумента (вместо этого был выбран экземпляр classobj)

В Python я пытаюсь запустить метод в классе, и я получаю сообщение об ошибке:

Traceback (most recent call last):
  File "C:\Users\domenico\Desktop\py\main.py", line 8, in <module>
    fibo.f()
  TypeError: unbound method f() must be called with fibo instance 
  as first argument (got nothing instead)

Код: (swineflu.py)

class fibo:
    a=0
    b=0

    def f(self,a=0):
        print fibo.b+a
        b=a;
        return self(a+1)

Script main.py

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

Что означает эта ошибка? Что вызывает эту ошибку?

Ответ 1

ОК, прежде всего, вам не нужно получать ссылку на модуль на другое имя; у вас уже есть ссылка (из import), и вы можете просто использовать ее. Если вы хотите другое имя, просто используйте import swineflu as f.

Во-вторых, вы получаете ссылку на класс, а не на экземпляр класса.

Итак, это должно быть:

import swineflu

fibo = swineflu.fibo()  # get an instance of the class
fibo.f()                # call the method f of the instance

Связанный метод - это метод, который привязан к экземпляру объекта. Несвязанный метод - это, конечно, тот, который не привязан к экземпляру. Обычно ошибка означает, что вы вызываете метод в классе, а не на экземпляр, что в точности соответствует тому, что происходило в этом случае, потому что вы не создали экземпляр класса.

Ответ 2

Как воспроизвести эту ошибку с минимальным количеством строк:

>>> class C:
...   def f(self):
...     print "hi"
...
>>> C.f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method f() must be called with C instance as 
first argument (got nothing instead)

Он терпит неудачу из-за TypeError, потому что вы не создавали экземпляр класса сначала, у вас есть два варианта: 1: либо сделать метод статическим, чтобы вы могли запускать его статическим способом, либо 2: создать экземпляр класса, чтобы у вас был экземпляр для захвата, чтобы запустить метод.

Похоже, вы хотите запустить метод статическим способом, сделайте следующее:

>>> class C:
...   @staticmethod
...   def f():
...     print "hi"
...
>>> C.f()
hi

Или, скорее всего, вы должны использовать экземпляр экземпляра следующим образом:

>>> class C:
...   def f(self):
...     print "hi"
...
>>> c1 = C()
>>> c1.f()
hi
>>> C().f()
hi

Если это вас смущает, задайте следующие вопросы:

  • В чем разница между поведением статического метода и поведением нормального метода?
  • Что значит создавать экземпляр класса?
  • Различия между действиями статических методов и нормальными методами.
  • Различия между классом и объектом.

Ответ 3

fibo = f.fibo ссылается на сам класс. Вероятно, вы захотели fibo = f.fibo() (обратите внимание на круглые скобки), чтобы создать экземпляр класса, после чего fibo.f() должно быть выполнено правильно.

f.fibo.f() терпит неудачу, потому что вы по существу вызываете f(self, a=0) без предоставления self; self автоматически привязывается, если у вас есть экземпляр класса.

Ответ 4

f - метод (экземпляр). Однако вы вызываете его через fibo.f, где fibo - объект класса. Следовательно, f является несвязанным (не привязанным к какому-либо экземпляру класса).

Если вы сделали

a = fibo()
a.f()

тогда f привязан (к экземпляру a).

Ответ 5

import swineflu

x = swineflu.fibo()   # create an object `x` of class `fibo`, an instance of the class
x.f()                 # call the method `f()`, bound to `x`. 

Здесь - хороший учебник для начала работы с классами на Python.

Ответ 6

В Python 2 (3 имеет другой синтаксис):

Что делать, если вы не можете создать экземпляр родительского класса, прежде чем вам нужно будет вызвать один из его методов?

Используйте super(ChildClass, self).method() для доступа к родительским методам.

class ParentClass(object):
    def method_to_call(self, arg_1):
        print arg_1

class ChildClass(ParentClass):
    def do_thing(self):
        super(ChildClass, self).method_to_call('my arg')

Ответ 7

Различия в версии python 2 и 3:

Если у вас уже есть метод по умолчанию в классе с тем же именем, и вы повторно объявляете его как одноименное имя, он будет отображаться как вызов unbound-метода этого экземпляра класса, если вы хотите его создать.

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

Метод экземпляра - это метод, который используется, когда создается экземпляр класса.

Примером может быть

   def user_group(self):   #This is an instance method
        return "instance method returning group"

Метод метки класса:

   @classmethod
   def user_group(groups):   #This is an class-label method
        return "class method returning group"

В версиях python 2 и 3 отличается класс @classmethod для записи в python 3 он автоматически получает это как метод метки класса и не нужно писать @classmethod Я думаю, это может помочь вам.