il metodo non associato f () deve essere chiamato con l'istanza fibo_ come primo argomento (ha invece l'istanza classobj)


139

In Python, sto cercando di eseguire un metodo in una classe e ottengo un errore:

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)

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

Cosa significa questo errore? Cosa sta causando questo errore?


1
Vuoi creare un'istanza di un oggetto o no?
Thomas,

2
Il nome della classe deve essere in maiuscolo.
CDT,

1
fibo = f.fibo()È necessario installare la classe tra parentesi.
Kotlinboy,

Puoi usarefibo().f()
Benyamin Jafari il

Risposte:


179

OK, prima di tutto, non è necessario ottenere un riferimento al modulo con un nome diverso; hai già un riferimento (dal import) e puoi semplicemente usarlo. Se vuoi un nome diverso basta usare import swineflu as f.

In secondo luogo, stai ottenendo un riferimento alla classe anziché creare un'istanza della classe.

Quindi questo dovrebbe essere:

import swineflu

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

Un metodo associato è un metodo collegato a un'istanza di un oggetto. Un metodo non associato è, ovviamente, uno che non è associato a un'istanza. L'errore di solito significa che stai chiamando il metodo sulla classe piuttosto che su un'istanza, che è esattamente ciò che stava accadendo in questo caso perché non hai istanziato la classe.


1
Puoi anche farlo swineflu.fibo().f()se lo chiami solo una volta.
Kit

81

Come riprodurre questo errore con il minor numero di righe possibile:

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

Non riesce a causa di TypeError perché non hai istanziato prima la classe, hai due possibilità: 1: rendere statico il metodo in modo da poterlo eseguire in modo statico oppure 2: creare un'istanza della classe in modo da avere un'istanza da prendere su, per eseguire il metodo.

Sembra che tu voglia eseguire il metodo in modo statico, fai come segue:

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

Oppure, ciò che probabilmente intendevi è usare l'istanza istanziata in questo modo:

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

Se questo ti confonde, fai queste domande:

  1. Qual è la differenza tra il comportamento di un metodo statico e il comportamento di un metodo normale?
  2. Cosa significa creare un'istanza di una classe?
  3. Differenze tra le modalità di esecuzione dei metodi statici rispetto ai metodi normali.
  4. Differenze tra classe e oggetto.

Ho istanziato la mia classe ma funziona solo quando uso @staticmethod. Questo può essere spiegato?
abeltre1,

9

fibo = f.fibofa riferimento alla classe stessa. Probabilmente hai voluto fibo = f.fibo()(notare le parentesi) creare un'istanza della classe, dopodiché fibo.f()dovrebbe avere successo correttamente.

f.fibo.f()fallisce perché stai essenzialmente chiamando f(self, a=0)senza fornire self; selfviene "associato" automaticamente quando si dispone di un'istanza della classe.


4

fè un metodo (istanza). Tuttavia, lo stai chiamando tramite fibo.f, dove si fibotrova l'oggetto classe. Quindi, fnon è associato (non associato a nessuna istanza di classe).

Se avete fatto

a = fibo()
a.f()

allora questo fè legato (all'istanza 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`. 

Ecco un buon tutorial per iniziare con le lezioni in Python.


2

In Python 2 (3 ha una sintassi diversa):

Cosa succede se non è possibile creare un'istanza della classe Parent prima di dover chiamare uno dei suoi metodi?

Utilizzare super(ChildClass, self).method()per accedere ai metodi parent.

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

Differenze nelle versioni In python 2 e 3:

Se hai già un metodo predefinito in una classe con lo stesso nome e dichiari nuovamente lo stesso nome, apparirà come chiamata di metodo non associato di quell'istanza di classe quando desideri istanziarlo.

Se volevi metodi di classe, ma invece li hai dichiarati come metodi di istanza.

Un metodo di istanza è un metodo utilizzato quando creare un'istanza della classe.

Un esempio sarebbe

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

Metodo dell'etichetta di classe:

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

Nella versione 2 e 3 di Python differiscono dalla classe @classmethod per scrivere in Python 3, questo viene automaticamente ottenuto come metodo di etichetta di classe e non è necessario scrivere @classmethod Penso che ciò possa aiutarti.


0

Prova questo. Per python 2.7.12 dobbiamo definire il costruttore o aggiungere auto a ciascun metodo seguito dalla definizione di un'istanza di una classe chiamata 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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.