2016-04-02 4 views
0

Ich erhalte einen Fehler beim Aufruf einer Methode, aber das Objekt, auf dem die Methode aufgerufen wird, definiert diese Methode.TypeError beim Aufruf einer ungebundenen Methode, aber Klasse _does_ definiere diese Methode

Hier ist, wo die Methode aufgerufen wird:

def interpreter(self, ast, expression, stack) # method in Parser.py file 
    ... 
    elif isinstance(ast, ReadNode): 
      self.interpret(ast.location, environment, stack) 
      loc = stack.pop() 
      input = sys.stdin.read() 
      try: 
       num = int(input) 
      except: 
       sys.stderr.write("error: not an integer") 
      loc.set(num) 
    ... 

ich einen Fehler bin immer auf loc.set(num)

Traceback (most recent call last): 
    File "/home/filepath/Parser.py", line 846, in <module> 
    main() 
    File "/home/filepath/Parser.py", line 844, in main 
    p.parse() 
    File "/home/filepath/Parser.py", line 75, in parse 
    self.interpret(instructions, environment, stack) 
    File "/home/filepath/Parser.py", line 128, in interpret 
    loc.set(num) 
TypeError: unbound method set() must be called with IntegerBox instance as first argument (got int instance instead) 

Hier ist die IntegerBox Klasse:

from Box import Box 

class IntegerBox(Box): 

    def __init__(self, value=0): 
     self.value = value 

    def get(self): 
     return self.value 

    def set(self, value): 
     self.value = value 

Wenn ich durch Der Debugger, um den Typ loc zu überprüfen, ist ein IntegerBox Instanz. Warum denkt es, dass loc dann keine IntegerBox-Instanz ist?

+0

Sie müssen den Code von "interpretieren" zeigen. – BrenBarn

Antwort

2

loc ist keine Instanz von IntegerBox, es ist die IntegerBox-Klasse.

Zum Beispiel:

>>> class C(object): 
...  def m(self): 
...   pass 
... 
>>> C.m() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method m() must be called with C instance as first argument (got nothing instead) 

aber:

>>> c = C() # create an instance 
>>> c.m() # no error 
>>> 

Sie müssen prüfen, was setzen in den Stapel Objekt wird.

Edit: ungebundene Methoden

erklärt Wenn eine Methode auf einer Instanz aufgerufen wird, wird die Instanz implizit als erster Parameter übergeben - das ist die self Parameter in der Methodensignatur ist. Wenn die Methode für die Klasse und nicht für eine Instanz aufgerufen wird, muss eine Instanz explizit übergeben werden, andernfalls wird TypeError für eine ungebundene Methode ausgelöst, da die Methode nicht an eine bestimmte Instanz der Klasse gebunden ist. So

: C.m() wirft ein TypeError

C().m() ok ist

C.m(C()) ist auch ok!

+0

Aus Neugier, woher wussten Sie, dass die Klasse an Stelle des Objekts aufgerufen wurde? –

+0

@ JeremyFisher weil das eine ungebundene Methode bedeutet - ich habe mehr zur Antwort hinzugefügt. – snakecharmerb

+1

Wir können auch sagen, dass dies Python 2 ist, weil Python 3 mit ungebundenen Methoden als separater Typ weggefallen ist ... Sie haben nie einen Nutzen für die Unterscheidung gefunden, also sind "ungebundene Methoden" nur normale Funktionen in Python 3. Sie können mache immer noch den gleichen Fehler --- benutze den Klassennamen anstelle eines Instanznamens --- aber die Fehlermeldung wäre "TypeError: m() nimmt genau ein Positionsargument (0 gegeben)", wie jede andere Funktion auch. –

Verwandte Themen