Die ungebundene Methode f () muss mit der fibo_-Instanz als erstem Argument aufgerufen werden (stattdessen die classobj-Instanz erhalten).

139

In Python versuche ich, eine Methode in einer Klasse auszuführen, und es wird eine Fehlermeldung angezeigt:

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)

Skript main.py

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

Was bedeutet dieser Fehler? Was verursacht diesen Fehler?

DomeWTF
quelle
1
Möchten Sie ein Objekt instanziieren oder nicht?
Thomas
2
Der Klassenname sollte groß geschrieben werden.
CDT
1
fibo = f.fibo()Die Klasse muss mit Klammern instanziiert werden.
Kotlinboy
Sie können verwendenfibo().f()
Benyamin Jafari

Antworten:

179

OK, zunächst müssen Sie keinen Verweis auf das Modul in einem anderen Namen erhalten. Sie haben bereits eine Referenz (aus dem import) und können diese einfach verwenden. Wenn Sie einen anderen Namen möchten, verwenden Sie einfach import swineflu as f.

Zweitens erhalten Sie einen Verweis auf die Klasse, anstatt die Klasse zu instanziieren.

Das sollte also sein:

import swineflu

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

Eine gebundene Methode ist eine Methode , die an eine Instanz eines Objekts angehängt ist. Eine ungebundene Methode ist natürlich eine, die nicht an eine Instanz gebunden ist . Der Fehler bedeutet normalerweise, dass Sie die Methode für die Klasse und nicht für eine Instanz aufrufen. Genau dies geschah in diesem Fall, weil Sie die Klasse nicht instanziiert hatten.

irgendwie
quelle
1
Sie können dies auch tun, swineflu.fibo().f()wenn Sie es nur einmal anrufen.
Kit
81

So reproduzieren Sie diesen Fehler mit möglichst wenigen Zeilen:

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

Dies schlägt aufgrund von TypeError fehl, da Sie die Klasse nicht zuerst instanziiert haben. Sie haben zwei Möglichkeiten: 1: Machen Sie die Methode entweder statisch, damit Sie sie statisch ausführen können, oder 2: Instanziieren Sie Ihre Klasse, damit Sie eine Instanz abrufen können auf, um die Methode auszuführen.

Es sieht so aus, als ob Sie die Methode statisch ausführen möchten. Gehen Sie folgendermaßen vor:

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

Oder Sie haben wahrscheinlich gemeint, die instanziierte Instanz wie folgt zu verwenden:

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

Wenn Sie dies verwirrt, stellen Sie folgende Fragen:

  1. Was ist der Unterschied zwischen dem Verhalten einer statischen Methode und dem Verhalten einer normalen Methode?
  2. Was bedeutet es, eine Klasse zu instanziieren?
  3. Unterschiede zwischen der Ausführung statischer Methoden und normalen Methoden.
  4. Unterschiede zwischen Klasse und Objekt.
Eric Leschinski
quelle
Ich habe meine Klasse instanziiert, aber es funktioniert nur, wenn ich @staticmethod verwende. Kann das erklärt werden?
abeltre1
9

fibo = f.fiboverweist auf die Klasse selbst. Sie wollten wahrscheinlich fibo = f.fibo()(beachten Sie die Klammern) eine Instanz der Klasse erstellen, danach fibo.f()sollte sie korrekt erfolgreich sein.

f.fibo.f()schlägt fehl, weil Sie im Wesentlichen anrufen, f(self, a=0)ohne zu liefern self; selfwird automatisch "gebunden", wenn Sie eine Instanz der Klasse haben.

Mark Rushakoff
quelle
4

fist eine (Instanz-) Methode. Sie rufen es jedoch über auf fibo.f, wo fibosich das Klassenobjekt befindet. Daher fist ungebunden (nicht an eine Klasseninstanz gebunden).

Wenn du. .. getan hast

a = fibo()
a.f()

dann fist das gebunden (an die Instanz a).

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

Hier ist ein gutes Tutorial, um mit Klassen in Python zu beginnen.

user225312
quelle
2

In Python 2 (3 hat eine andere Syntax):

Was ist, wenn Sie Ihre Elternklasse nicht instanziieren können, bevor Sie eine ihrer Methoden aufrufen müssen?

Verwenden Sie super(ChildClass, self).method()diese Option, um auf übergeordnete Methoden zuzugreifen.

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

Unterschiede in In Python 2 und 3 Version:

Wenn Sie bereits eine Standardmethode in einer Klasse mit demselben Namen haben und diese erneut als denselben Namen deklarieren, wird sie als Aufruf einer ungebundenen Methode dieser Klasseninstanz angezeigt, wenn Sie sie instanziieren möchten.

Wenn Sie Klassenmethoden wollten, diese aber stattdessen als Instanzmethoden deklarierten.

Eine Instanzmethode ist eine Methode, die zum Erstellen einer Instanz der Klasse verwendet wird.

Ein Beispiel wäre

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

Klassenbeschriftungsmethode:

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

In Python 2 und 3 unterscheiden sich die Klassen @classmethod, um in Python 3 zu schreiben, automatisch als Klassenbeschriftungsmethode und müssen @classmethod nicht schreiben. Ich denke, dies könnte Ihnen helfen.

Projesh Bhoumik
quelle
0

Versuche dies. Für Python 2.7.12 müssen wir den Konstruktor definieren oder jeder Methode self hinzufügen, gefolgt von der Definition einer Instanz einer Klasse namens 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
quelle