O método não acoplado f () deve ser chamado com fibo_ instance como primeiro argumento (obteve a instância classobj)

139

No Python, estou tentando executar um método em uma classe e recebo um erro:

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)

Código: (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

O que esse erro significa? O que está causando esse erro?

DomeWTF
fonte
1
Deseja instanciar um objeto ou não?
Thomas
2
O nome da classe deve ser maiúsculo.
CDT
1
fibo = f.fibo()Precisa instanciar a classe entre colchetes.
Kotlinboy
Você pode usarfibo().f()
Benyamin Jafari

Respostas:

179

OK, primeiro de tudo, você não precisa obter uma referência para o módulo em um nome diferente; você já tem uma referência (da import) e pode apenas usá-la. Se você quiser um nome diferente, basta usar import swineflu as f.

Segundo, você está recebendo uma referência à classe em vez de instanciar a classe.

Portanto, isso deve ser:

import swineflu

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

Um método acoplado é aquele anexado a uma instância de um objeto. Um método não vinculado é, obviamente, aquele que não está anexado a uma instância. O erro geralmente significa que você está chamando o método na classe e não em uma instância, que é exatamente o que estava acontecendo neste caso, porque você não havia instanciado a classe.

kindall
fonte
1
Você também pode fazer swineflu.fibo().f()se estiver ligando apenas uma vez.
Kit
81

Como reproduzir este erro com o menor número possível de linhas:

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

Ele falha por causa de TypeError, porque você não instancia a classe primeiro, você tem duas opções: 1: tornar o método estático para que você possa executá-lo de maneira estática ou 2: instanciar sua classe para que você tenha uma instância a capturar para, para executar o método

Parece que você deseja executar o método de maneira estática, faça o seguinte:

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

Ou, o que você provavelmente quis dizer é usar a instância instanciada assim:

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

Se isso o confunde, faça estas perguntas:

  1. Qual é a diferença entre o comportamento de um método estático e o comportamento de um método normal?
  2. O que significa instanciar uma classe?
  3. Diferenças entre como os métodos estáticos são executados e os métodos normais.
  4. Diferenças entre classe e objeto.
Eric Leschinski
fonte
Instanciei minha classe, mas ela só funciona quando eu uso @staticmethod. Isso pode ser explicado?
precisa saber é o seguinte
9

fibo = f.fiboreferencia a própria classe. Você provavelmente desejou fibo = f.fibo()(observe os parênteses) criar uma instância da classe, após a qual fibo.f()deve ter sucesso corretamente.

f.fibo.f()falha porque você está essencialmente ligando f(self, a=0)sem fornecer self; selfé "vinculado" automaticamente quando você tem uma instância da classe.

Mark Rushakoff
fonte
4

fé um método (instância). No entanto, você está chamando-o via fibo.f, onde fiboestá o objeto de classe. Portanto, fé ilimitado (não vinculado a nenhuma instância de classe).

Se você fez

a = fibo()
a.f()

então isso festá vinculado (à instância a).

lijie
fonte
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`. 

Aqui está um bom tutorial para começar as aulas em Python.

user225312
fonte
2

No Python 2 (3 tem sintaxe diferente):

E se você não conseguir instanciar sua classe Parent antes de precisar chamar um de seus métodos?

Use super(ChildClass, self).method()para acessar os métodos pai.

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')
Peter Graham
fonte
0

Diferenças nas versões python 2 e 3:

Se você já possui um método padrão em uma classe com o mesmo nome e o declara novamente, ele aparecerá como uma chamada de método não acoplado dessa instância de classe quando você a instanciar.

Se você queria métodos de classe, mas os declarou como métodos de instância.

Um método de instância é um método usado quando criar uma instância da classe.

Um exemplo seria

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

Método do rótulo da classe:

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

Nas versões python 2 e 3 diferem a classe @classmethod para escrever no python 3, obtém-o automaticamente como um método de rótulo de classe e não precisa escrever @classmethod. Acho que isso pode ajudá-lo.

Projesh Bhoumik
fonte
0

Tente isso. Para python 2.7.12, precisamos definir o construtor ou adicionar self a cada método, seguindo a definição de uma instância de uma classe chamada object.

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)
NIKHIL BHALODIYA
fonte