La méthode non liée f () doit être appelée avec l'instance fibo_ comme premier argument (a obtenu l'instance classobj à la place)

139

En Python, j'essaye d'exécuter une méthode dans une classe et j'obtiens une erreur:

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)

Code: (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

Que signifie cette erreur? Qu'est ce qui cause cette erreur?

DomeWTF
la source
1
Voulez-vous instancier un objet ou non?
Thomas
2
Le nom de la classe doit être en majuscule.
CDT
1
fibo = f.fibo()Besoin d'instancier la classe avec des crochets.
Kotlinboy
Vous pouvez utiliserfibo().f()
Benyamin Jafari

Réponses:

179

OK, tout d'abord, vous n'avez pas besoin d'obtenir une référence au module sous un nom différent; vous avez déjà une référence (de la import) et vous pouvez simplement l'utiliser. Si vous voulez un autre nom, utilisez simplement import swineflu as f.

Deuxièmement, vous obtenez une référence à la classe plutôt que l'instanciation de la classe.

Cela devrait donc être:

import swineflu

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

Une méthode liée est une méthode qui est attachée à une instance d'un objet. Une méthode indépendante est, bien entendu, une méthode qui n'est pas attachée à une instance. L'erreur signifie généralement que vous appelez la méthode sur la classe plutôt que sur une instance, ce qui est exactement ce qui se passait dans ce cas parce que vous n'aviez pas instancié la classe.

kindall
la source
1
Vous pouvez également le faire swineflu.fibo().f()si vous ne l'appelez qu'une seule fois.
Kit
81

Comment reproduire cette erreur avec le moins de lignes possible:

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

Il échoue à cause de TypeError parce que vous n'avez pas instancié la classe en premier, vous avez deux choix: 1: soit rendre la méthode statique pour pouvoir l'exécuter de manière statique, soit 2: instancier votre classe pour avoir une instance à saisir sur, pour exécuter la méthode.

Il semble que vous souhaitiez exécuter la méthode de manière statique, procédez comme suit:

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

Ou, ce que vous vouliez probablement est d'utiliser l'instance instanciée comme ceci:

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

Si cela vous déroute, posez ces questions:

  1. Quelle est la différence entre le comportement d'une méthode statique et le comportement d'une méthode normale?
  2. Que signifie instancier une classe?
  3. Différences entre la manière dont les méthodes statiques sont exécutées et les méthodes normales.
  4. Différences entre classe et objet.
Eric Leschinski
la source
J'ai instancié ma classe mais cela ne fonctionne que lorsque j'utilise @staticmethod. Cela peut-il être expliqué?
abeltre1
9

fibo = f.fibofait référence à la classe elle-même. Vous vouliez probablement fibo = f.fibo()(notez les parenthèses) créer une instance de la classe, après quoi fibo.f()devrait réussir correctement.

f.fibo.f()échoue parce que vous appelez essentiellement f(self, a=0)sans fournir self; selfest "lié" automatiquement lorsque vous avez une instance de la classe.

Mark Rushakoff
la source
4

fest une méthode (d'instance). Cependant, vous l'appelez via fibo.f, où se fibotrouve l'objet de classe. Par conséquent, fest non lié (non lié à une instance de classe).

Si tu as fait

a = fibo()
a.f()

alors cela fest lié (à l'instance a).

lijie
la source
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`. 

Voici un bon tutoriel pour démarrer avec les classes en Python.

user225312
la source
2

En Python 2 (3 a une syntaxe différente):

Que faire si vous ne pouvez pas instancier votre classe Parent avant d'avoir besoin d'appeler l'une de ses méthodes?

Utilisez super(ChildClass, self).method()pour accéder aux méthodes parentes.

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
la source
0

Différences dans les versions python 2 et 3:

Si vous avez déjà une méthode par défaut dans une classe avec le même nom et que vous la déclarez à nouveau sous le même nom, elle apparaîtra comme un appel de méthode non liée de cette instance de classe lorsque vous vouliez l'instancier.

Si vous vouliez des méthodes de classe, mais que vous les avez déclarées comme méthodes d'instance à la place.

Une méthode d'instance est une méthode utilisée pour créer une instance de la classe.

Un exemple serait

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

Méthode d'étiquette de classe:

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

Dans les versions python 2 et 3, la classe @classmethod diffère pour écrire en python 3, elle l'obtient automatiquement en tant que méthode d'étiquette de classe et n'a pas besoin d'écrire @classmethod, je pense que cela pourrait vous aider.

Projesh Bhoumik
la source
0

Essaye ça. Pour python 2.7.12, nous devons définir le constructeur ou ajouter self à chaque méthode, puis définir une instance d'une classe appelée objet.

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