Спосіб незв’язаного f () повинен бути викликаний з екземпляром fibo_ як перший аргумент (замість цього отриманий екземпляр classobj)


139

У 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)

Сценарій main.py

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

Що означає ця помилка? Що викликає цю помилку?


1
Ви хочете вставити об'єкт чи ні?
Томас

2
Назву класу слід використовувати з великої літери.
CDT

1
fibo = f.fibo()Потрібно інстанціювати клас дужками.
Котлінбой

Можна скористатисяfibo().f()
Бенямін Джафарі

Відповіді:


179

Гаразд, по-перше, вам не потрібно отримувати посилання на модуль на інше ім'я; у вас вже є посилання (від 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

Пов'язаний метод є той , який приєднаний до примірника об'єкта. Незв'язані методи , звичайно, той , який НЕ приєднаний до примірника. Помилка, як правило, означає, що ви викликаєте метод на класі, а не на екземпляр. Це саме те, що відбувається в цьому випадку, тому що ви не інстанціювали клас.


1
Ви також можете зробити це, swineflu.fibo().f()якщо ви телефонуєте лише один раз.
Кіт

81

Як відтворити цю помилку якомога менше рядків:

>>> 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

Якщо це вас бентежить, задайте наступні питання:

  1. Чим відрізняється поведінка статичного методу від поведінки нормального методу?
  2. Що означає інстанціювати клас?
  3. Відмінність того, як статичні методи проводяться проти звичайних методів.
  4. Відмінності між класом і об'єктом.

Я створив свій клас, але він працює лише тоді, коли я використовую @staticmethod. Чи можна це пояснити?
abeltre1

9

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).


2
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.


2

У 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')

0

Відмінності у версії python 2 та 3:

Якщо у вас вже є метод за замовчуванням у класі з тим самим іменем, і ви повторно заявляєте як те саме ім'я, він буде відображатися як виклик без зв’язку методу цього примірника класу, коли ви хотіли його ініціювати.

Якщо ви хотіли методи класу, але ви оголосили їх як методи екземпляра.

Метод екземпляра - це метод, який використовується при створенні екземпляра класу.

Прикладом може бути

   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 Я думаю, що це може вам допомогти.


0

Спробуйте це. Для python 2.7.12 нам потрібно визначити конструктор або потрібно додати self до кожного методу з подальшим визначенням примірника класу, який називається об'єктом.

import cv2

class calculator:

#   def __init__(self):

def multiply(self, a, b):
    x= a*b
    print(x)

def subtract(self, a,b):
    x = a-b
    print(x)

def add(self, a,b):
    x = a+b
    print(x)

def div(self, a,b):
    x = a/b
    print(x)

 calc = calculator()
 calc.multiply(2,3)
 calc.add(2,3)
 calc.div(10,5)
 calc.subtract(2,3)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.