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
Я думаю, это может помочь вам.