el método independiente f () debe llamarse con fibo_ instance como primer argumento (en su lugar, obtuve instancia classobj)


139

En Python, intento ejecutar un método en una clase y aparece un error:

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

¿Qué significa este error? Que esta causando este error?


1
¿Quieres instanciar un objeto o no?
Thomas

2
El nombre de la clase debe estar en mayúscula.
CDT

1
fibo = f.fibo()Necesita instanciar la clase entre paréntesis.
Kotlinboy

Puedes usarfibo().f()
Benyamin Jafari

Respuestas:


179

OK, antes que nada, no tiene que obtener una referencia al módulo con un nombre diferente; ya tienes una referencia (del import) y puedes usarla. Si quieres un nombre diferente solo usaimport swineflu as f .

En segundo lugar, está obteniendo una referencia a la clase en lugar de crear una instancia de la clase.

Entonces esto debería ser:

import swineflu

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

Un método enlazado es uno que está adjunto a una instancia de un objeto. Un método independiente es, por supuesto, uno que no está asociado a una instancia. El error generalmente significa que está llamando al método en la clase en lugar de en una instancia, que es exactamente lo que estaba sucediendo en este caso porque no había instanciado la clase.


1
También podría hacerlo swineflu.fibo().f()si solo lo llama una vez.
Kit

81

Cómo reproducir este error con la menor cantidad de líneas posible:

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

Falla debido a TypeError porque no instanciaste la clase primero, tienes dos opciones: 1: hacer que el método sea estático para que puedas ejecutarlo de forma estática, o 2: instanciar tu clase para que tengas una instancia para tomar en, para ejecutar el método.

Parece que desea ejecutar el método de forma estática, haga esto:

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

O bien, lo que probablemente quiso decir es usar la instancia instanciada de esta manera:

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

Si esto te confunde, haz estas preguntas:

  1. ¿Cuál es la diferencia entre el comportamiento de un método estático y el comportamiento de un método normal?
  2. ¿Qué significa crear una instancia de una clase?
  3. Diferencias entre cómo se ejecutan los métodos estáticos frente a los métodos normales.
  4. Diferencias entre clase y objeto.

He instanciado mi clase pero solo funciona cuando uso @staticmethod. ¿Se puede explicar eso?
abeltre1

9

fibo = f.fibohace referencia a la clase misma. Probablemente quería fibo = f.fibo()(tenga en cuenta los paréntesis) hacer una instancia de la clase, después de lo cualfibo.f() debería tener éxito correctamente.

f.fibo.f()falla porque esencialmente está llamando f(self, a=0)sin suministrar self; selfse "vincula" automáticamente cuando tiene una instancia de la clase.


4

fes un método (instancia) Sin embargo, lo está llamando a través de fibo.f, donde fiboestá el objeto de clase. Por lo tanto,f no está vinculado (no está vinculado a ninguna instancia de clase).

Si lo hiciste

a = fibo()
a.f()

entonces eso festá vinculado (a la instancia 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`. 

Aquí hay un buen tutorial para comenzar con las clases en Python.


2

En Python 2 (3 tiene una sintaxis diferente):

¿Qué sucede si no puede crear una instancia de su clase Parent antes de que necesite llamar a uno de sus métodos?

Se usa super(ChildClass, self).method()para acceder a los métodos principales.

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

Diferencias en las versiones de Python 2 y 3:

Si ya tiene un método predeterminado en una clase con el mismo nombre y vuelve a declararlo con el mismo nombre, aparecerá como una llamada a método no vinculado de esa instancia de clase cuando desee instanciarlo.

Si quería métodos de clase, pero los declaró como métodos de instancia en su lugar.

Un método de instancia es un método que se utiliza cuando se crea una instancia de la clase.

Un ejemplo sería

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

Método de etiqueta de clase:

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

En las versiones de python 2 y 3 difieren la clase @classmethod para escribir en python 3, lo obtiene automáticamente como un método de etiqueta de clase y no necesita escribir @classmethod. Creo que esto podría ayudarlo.


0

Prueba esto. Para python 2.7.12 necesitamos definir un constructor o agregar uno mismo a cada método seguido de definir una instancia de una clase llamada objeto.

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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.