(Python) TypeError: 'int' object is not callable
Julian von Mendel
- sonstiges
Hi,
folgende Fehlermeldung in einem Python-QT-Programm das Threading verwendet:
--
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.4/threading.py", line 442, in __bootstrap
self.run()
File "/home/jvm/Documents/prj/ccs/simulation/class_control.py", line 101, in run
self.addcar(0)
File "/home/jvm/Documents/prj/ccs/simulation/class_control.py", line 144, in addcar
self.objlist.append(car(self,self.simul,start,ziel,typ).start())
TypeError: 'int' object is not callable
--
car ist eine Threading-Klasse, da ich mehrere Instanzen initialisiere (mir ist bewusst, das man mit der Anzahl der Threading-Klassen nicht übertreiben sollte) speichere ich diese in der Liste objlist. Ich habe das Problem auf folgende Zeile der Klasse eingeschränkt:
self.obj = QLabel(simul.frame5,self.getName())
Entferne ich diese, taucht die Fehlermeldung nicht auf. Die Zeile ist aber wichtig... Interessanterweise habe ich noch eine andere Klasse, in der die gleiche Zeile vorkommt, die aber funktioniert. Kann mir jemand erklären, was die Fehlermeldung bedeutet, und was ich dagegen tun kann? Dabei ist zu beachten, dass meine Python-Kenntnisse nur sehr rudimentär sind...
Vielen Dank
Julian
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
Hallo Tim.
Wird der Themenbereich „Python“ nun dauerhaft hinzugefügt?
Einen schönen Freitag noch.
Gruß, Ashura
Hallo Ashura,
Wird der Themenbereich „Python“ nun dauerhaft hinzugefügt?
Kann sein, kann nicht sein.
Im Ernst: Das war gerade ein Alleingang und Schnellschuß von mir, basierend auf einem lahmen Scherz vor einiger Zeit im Chat. Allerdings wollte ich unter uns Devs wirklich mal eine Diskussion über eine Neugestaltung der Themenbereiche anstoßen, ich muss da noch das angetextete Posting mit Vorschlägen und Begründungen dazu vervollständigen und posten, so wie ich noch so vieles Angetextetes vervollständigen muss. Wenn diese Diskussion erfolgreich wird, werden die Themenbereiche aktualisiert, eventuell bleibt dann auch Python darunter. Wenn nicht, dann kriege ich morgen früh von den liebenswerten Mit-Devs die Hucke voll. ;)
Ich möchte die Diskussion, _welche_ Kategorien neu einzuführen wären, aber lieber im kleinen Kreis – soll heissen: unter den Developern – führen, zum einen gab es da schon Vorschläge, des weitereren gibt es da eine Abstimmung auf sonstige Bereiche in SELFHTML und vor allem, weil dann jeder hier ankommt, und sein persönliches Steckenpferd (RUBY, C, C#, LISP, JSON, RSS, RDF, AJAX, OWL, BUZZWORD-DU-JOUR, ...) aufgenommen haben will, so wie Python mein derzeitiges persönliches Steckenpferd ist. Das dann im Sinne der Demokratie auch wieder rausfliegen könnte, ja. Einen Überblick über aktuelle und auch eventuelle zukünftige Webtechnologien haben wir Developer in unserem vielköpfigen Team durchaus, es geht weniger um Vorschläge, sondern darum, daraus eine sinnvolle Auswahl zu treffen.
Tim
Hallo Tim.
Wird der Themenbereich „Python“ nun dauerhaft hinzugefügt?
Kann sein, kann nicht sein.
Ich war so frei, diesen nun vorerst einmal meinem User-JS hinzuzufügen, daher auch meine Frage.
Ich möchte die Diskussion, _welche_ Kategorien neu einzuführen wären, aber lieber im kleinen Kreis – soll heissen: unter den Developern – führen, […]
Kann ich nachvollziehen. Eine vernünfigte Auswahl wäre sehr befürwortenswert, da die derzeitige mitunter recht unübersichtlich und im gleichen Zuge doch wiederum nicht ausreichend ist.
Würde es nicht im Chaos enden, könnte eine Eigeneingabe des angezielten Themebereiches auch in Erwägung gezogen werden. (In etwa wie vor der Aktualisierung der betroffenen Stelle in der Forensoftware, nur eben mit offiziellem Eingabefeld.)
Einen schönen Freitag noch.
Gruß, Ashura
Moin,
Würde es nicht im Chaos enden, könnte eine Eigeneingabe des angezielten Themebereiches auch in Erwägung gezogen werden. (In etwa wie vor der Aktualisierung der betroffenen Stelle in der Forensoftware, nur eben mit offiziellem Eingabefeld.)
Ach, am einfachsten macht man das vollständig Buzzword- und Web-2.0-kompatibel und nimmt ... Tags.
Hallo Tim,
Allerdings wollte ich unter uns Devs wirklich mal eine Diskussion über eine Neugestaltung der Themenbereiche anstoßen, ich muss da noch das angetextete Posting mit Vorschlägen und Begründungen dazu vervollständigen und posten, so wie ich noch so vieles Angetextetes vervollständigen muss.
Da Du das jetzt so toll angekündigt hast, bin ich sehr gespannt. ;-)
Viele Grüße,
Christian
Hallo.
Kann sein, kann nicht sein.
Nein, genau das nicht.
MfG, at
Hey Tim,
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.
du hast Recht, das war das Problem. Ich habe das Attribut "start" umgenannt und die Methode lies sich problemlos aufrufen. Primitiver Fehler an dem ich lange saß, einfach, weil ich die Fehlermeldung nicht verstanden habe. Danke für die Hilfe.
Schöne Grüße
Julian
Hi,
was ich noch nicht verstanden habe, ist, warum diese eine Zeile in der Klasse die Fehlermeldung beeinflusst hat. Sie hat ja weder mit der Methode, noch mit dem Attribut "start" etwas zu tun?!
Schöne Grüße
Julian