Tim Tepaße: TypeError: 'int' object is not callable

Beitrag lesen

Hallo Julian,

da Du den Quellcode Deiner car-Klasse nicht veröffentlicht hast, stürze ich mich mal auf die Fehlermeldung, ich vermute nämlich, es ist nicht so kompliziert, wie es scheint:

self.objlist.append(car(self,self.simul,start,ziel,typ).start())
TypeError: 'int' object is not callable

Hier wird ein TypeError geworfen, laut Python Library Reference geschieht dass immer dann, wenn:

"Raised when an operation or function is applied to an object of inappropriate
  type. The associated value is a string giving details about the type mismatch."

Und tatsächlich, man sagt Dir, dass das int-Objekt nicht aufrufbar (callable) ist. Wo geschieht da ein call auf ein int-Objekt? Tja, man weiss es nicht, ohne die Definitionen von objlist.append() oder car(object) oder car.start() zu kennen. Ich habe jedoch eine Vermutung. Und zwar haben in Python bei Namenskonflikten zwischen Attributen und Methoden einer Klasse erstere den Vorrang:

"Data attributes override method attributes with the same name; to avoid
  accidental name conflicts, which may cause hard-to-find bugs in large programs,
  it is wise to use some kind of convention that minimizes the chance of
  conflicts." (Python Tutorial)

Als Argument von objlist.append() hast Du einen Aufruf der Methode car.start(). Zeitgleich kriegt das car-Objekt noch einen Parameter namens start, ich vermute, dieser Parameter wird wohl im Konstruktor des car-Objekts zu einem Attribut des Objektes, sprich self.start. Da hätten wir einen Namenskonflikt.

Das kann man auch im interaktiven Python Interpreter ausprobieren. Erstmal eine passende Klasse definieren ...

class bla(object):  
    def __init__(self, start=1)  
        self.start = start  
    def start(self):  
        pass

... und dann damit im Interpreter etwas rumspielen. Objekte dieser Klasse lassen sich bequem erzeugen:

b = bla(3)

Und auch auf das Attribut start lässt sich wunderbar zugreifen:

b.start

3

Aber ruft man die Methode start() auf, kriegt man ein Problem:

b.start()

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'int' object is not callable

Denn es wird versucht, das die Methode b.start() überschreibende Attribut b.start aufzurufen. Nur b.start ist nicht aufrufbar, was man mit der eingebauten Funktion callable() überprüfen kann:

callable(b.start)

False

Dass es tatsächlich nur einen Namen „start“ im Objekt b gibt, kann man mit der eingebauten Funktion dir() überprüfen:

dir(b)

['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'start']

Ignoriert man die Methoden für Operator Overloading, findet sich da tatsächlich nur der Name „start“.

Was kannst Du nun tun? Wie das Python Tutorial oben vorgeschlagen hat, entweder Dein Attribut car.start oder die Methode car.start() umbenennen. Ich selber würde wahrscheinlich einfach das Attribut in „startingpoint“ oder ein ähnliches Nomen umbenennen, dass man nicht mit einem – für Methoden benutzten – Verb verwechseln kann.

Tim