Ich will ein Objekt erzeugen mit
chart = MyChart()
die Init von MyChart enthält nur self als Argument.
In der Init selber werden keine weiteren Objekte (ausser arrays) erzeugt.
Trotzdem kriege ich folgende Fehlermeldung:
"__init__ takes exactly 2 arguments 1 given"
Wenn ich in die init 2 dummy argumente reinmache, so kommt immer noch die selbe Meldung.
=> es ist nicht diese init die einen Fehler wirft...welche dann??
Irgendwelche Ideen?
Klassenattributte umbn(__init__ aufruf...was ruft er da auf)
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Ohne Code wohl kaum...
Code: Alles auswählen
class MyChart(object):
def __init__(self):
self.rawData = []
self.calculatedData = []
self.lowerLimit = []
self.upperLimit = []
self.target = []
self.upperSpec = None
self.lowerSpec = None
self.specTarget = None
self.ooc = []
#self.db = queue.db
#self.calcData()
self.failures = []
Code: Alles auswählen
try:
chart = MyChart()
except Exception, e:
f = open("except.txt", "wr")
f.write(str(e))
f.close()
Also das ist der genaue Aufruf
Der Aufruf erfolgt auch aus einem externe Methodenobjekt in Zope wenn das eine Rolle spielt. (der Zugriff auf andere Klassen mit daraus funktioniert)
Das verrät der komplette Traceback.grandma hat geschrieben:Wenn ich in die init 2 dummy argumente reinmache, so kommt immer noch die selbe Meldung.
=> es ist nicht diese init die einen Fehler wirft...welche dann??
Möglicherweise ist da eine veraltete Version im Spiel.
Code: Alles auswählen
Traceback (most recent call last):
File "/usr/local/Zope-2.9.3/Extensions/web.py", line 81, in go
chart = MyChart()
TypeError: __init__() takes exactly 2 arguments (1 given)
- Sr4l
- User
- Beiträge: 1091
- Registriert: Donnerstag 28. Dezember 2006, 20:02
- Wohnort: Kassel
- Kontaktdaten:
Code: Alles auswählen
import sys
import traceback
"".join(
traceback.format_exception(
sys.exc_type,sys.exc_value,sys.exc_traceback))
Eine absolute Geek Methode wäre es __init__ so zu verändern das es 2 Variablen entgegennimmt und man lässt sich die zweite einmal ausgeben
*edit*
wie ich sehe hast du gerade die Traceback hin bekommen und wie ich sehe setzt du Zope ein. Kenne ich so nicht, aber bei ModPython ist es so, das man immer in einer Funktion als erstes die Variable `req` entgegen nimmt, so etwas wird es dann bei Zope auch sein.
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Bei der Instanzierung werden für jede Instanz alle diese Attribute mit dem Boolwert False gesetzt. Wenn das so bleiben soll, würde ich sie als Klassenattribute setzen.grandma hat geschrieben:Code: Alles auswählen
class MyChart(object): def __init__(self): self.rawData = [] self.calculatedData = [] self.lowerLimit = [] self.upperLimit = [] self.target = [] self.upperSpec = None self.lowerSpec = None self.specTarget = None self.ooc = [] #self.db = queue.db #self.calcData() self.failures = []
LG
rolgal_reloaded
Dann teilen sich alle Objekte dieses Typs die Attribute. Das ist *sehr* wahrscheinlich nicht das gewünschte Verhalten.
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Keine Ahnung was gewünscht ist, aber wenn alle Objekte die gleichen Werte bekommen, ohne dass sie beim Aufruf anders gesetzt werden können, macht das doch wenig Sinn sie als Instanzvariablen zu definieren, oder?BlackJack hat geschrieben:Dann teilen sich alle Objekte dieses Typs die Attribute. Das ist *sehr* wahrscheinlich nicht das gewünschte Verhalten.
Naja doch macht schon Sinn, das Objekt wird einer anderen Methode übergeben und da werden dann die Werte verändert.
Hier sollen dann die Werte natürlcih nicht für alle Instanzen verändert werden sondern nur für eine.
(und so 100prozentig fertig ist das ganze noch nicht)
Aber zurück zum Thema...
Das mit den mehreren Variablen übergeben hab ich schon ausprobiert (2 dummy argumente)
Die Fehlermeldung bleibt bei "2 Arguments expected"
Also ist es nicht die eigentlich Init die aufgerufen wird.
Ahja, das Requestobjekt wird zumindestens an die externe Methode über self übergeben, ist also kein extra Argument.
Edit: Wenn ich mir es so recht überlege, da es keinerlei andere Fehlermeldung gab als ich die Argumente geändert habe, glaube ich das es irgendeine alte version ist die er da her nimmt... weiss nur nicht woher gerade.
Hier sollen dann die Werte natürlcih nicht für alle Instanzen verändert werden sondern nur für eine.
(und so 100prozentig fertig ist das ganze noch nicht)
Aber zurück zum Thema...
Das mit den mehreren Variablen übergeben hab ich schon ausprobiert (2 dummy argumente)
Die Fehlermeldung bleibt bei "2 Arguments expected"
Also ist es nicht die eigentlich Init die aufgerufen wird.
Ahja, das Requestobjekt wird zumindestens an die externe Methode über self übergeben, ist also kein extra Argument.
Edit: Wenn ich mir es so recht überlege, da es keinerlei andere Fehlermeldung gab als ich die Argumente geändert habe, glaube ich das es irgendeine alte version ist die er da her nimmt... weiss nur nicht woher gerade.
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Die Werte können auch nur für eine Instanz geändert werden, wenn es Klassenattribute sind.
Oder überseh ich einen wesentlichen Unterschied:
Oder überseh ich einen wesentlichen Unterschied:
Code: Alles auswählen
>>> class A:
var1 = 5
var2 = 10
>>> class B:
def __init__(self):
self.var1 = 5
self.var2 = 10
>>> a1 = A()
>>> a2 = A()
>>> b1 = B()
>>> b2 = B()
>>> a1.var1
5
>>> a2.var1
5
>>> a1.var1 = 7
>>> a1.var1
7
>>> a2.var1
5
>>> b1.var1
5
>>> b2.var1
5
>>> b1.var1 = 7
>>> b1.var1
7
>>> b2.var1
5
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi,rolgal_reloaded hat geschrieben:Keine Ahnung was gewünscht ist, aber wenn alle Objekte die gleichen Werte bekommen, ohne dass sie beim Aufruf anders gesetzt werden können, macht das doch wenig Sinn sie als Instanzvariablen zu definieren, oder?BlackJack hat geschrieben:Dann teilen sich alle Objekte dieses Typs die Attribute. Das ist *sehr* wahrscheinlich nicht das gewünschte Verhalten.
nur weil es Initialisierungswerte sind, heißt das nicht, dass sie im Namensraum der Klasse besser aufgehoben sind. Die Frage ist, ob Änderungen in einer Instanz einen Einfluss auf die anderen Instanzen haben soll.
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
@Michael
Ich versteh das schon, nur wie oben gezeigt, lassen sich die Werte der einzelnen Instanzen ohne Einfluss aufeinander ändern.
LG
r_r
Ich versteh das schon, nur wie oben gezeigt, lassen sich die Werte der einzelnen Instanzen ohne Einfluss aufeinander ändern.
LG
r_r
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hallo Rolgal!
Wenn Du dem Namen innerhalb der Instanz ein neues Objekt zuweist, dann trennen sich genau da die Wege des Namens und Du greifst fortan von Klasse und Instanz auf unterschiedliche Objekte zu. Bis dahin referenzierten beide Namen (von Klasse und Instanz) dasselbe Objekt:
Wenn Du dem Namen aber kein neues Objekt zuweist, sondern dasselbe Objekt nur modifizierst (im folgenden Beispiel list.append), dann referenzierst Du weiterhin dasselbe Objekt mit demselben Namen:
Das kann erwünscht sein, aber auch nicht.
Grüße,
Michael
Ja, es geht darum, ob prinzipiell dasselbe Objekt an die Instanz weitergegeben wird, oder gleich eine Kopie - also ein anderes Objekt.rolgal_reloaded hat geschrieben:Die Werte können auch nur für eine Instanz geändert werden, wenn es Klassenattribute sind.
Oder überseh ich einen wesentlichen Unterschied:
Code: Alles auswählen
>>> class A: var1 = 5 var2 = 10
Wenn Du dem Namen innerhalb der Instanz ein neues Objekt zuweist, dann trennen sich genau da die Wege des Namens und Du greifst fortan von Klasse und Instanz auf unterschiedliche Objekte zu. Bis dahin referenzierten beide Namen (von Klasse und Instanz) dasselbe Objekt:
Code: Alles auswählen
>>> class A:
... var = 5
...
>>> a1, a2 = A(), A()
>>> a1.var, a2.var
(5, 5)
>>> A.var = 10
>>> a1.var, a2.var
(10, 10)
>>> a1.var = 15
>>> a1.var, a2.var
(15, 10)
Code: Alles auswählen
>>> class B:
... var = [5]
...
>>> b1, b2 = B(), B()
>>> b1.var, b2.var
([5], [5])
>>> B.var.append(10)
>>> b1.var, b2.var
([5, 10], [5, 10])
>>> b1.var.append(15)
>>> b1.var, b2.var
([5, 10, 15], [5, 10, 15])
Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Alles klar, aber wäre es nicht doch besser, die Defaultwerte in __init__ reinzuschreiben. Entspricht das nicht mehr der Idee eines Konstruktors?
Also:
Code: Alles auswählen
class A:
def __init__(self, var1 = [], var2 = []): #usw.
self.var1 = var1
self.var2 = var2
LG
rolgal_reloaded
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hi rolgal,rolgal_reloaded hat geschrieben:@Michael
Ich versteh das schon, nur wie oben gezeigt, lassen sich die Werte der einzelnen Instanzen ohne Einfluss aufeinander ändern.
LG
r_r
leider nicht. Es macht wirklich einen Unterschied, ob bei der Instanzierung einer Klasse eine Referenz auf das Objekt der Klasse übergeben wird, oder eine Kopie. In Deinem Beispiel hatte das Ändern des Integerwertes nur deshalb keinen Einfluss, weil Integerobjekte nicht veränderbar sind und Python nicht dem von der Klasse aus referenzierten Integerobjekt den Wert 5 gegeben hat, sondern statt dessen dem instanzlokalen Namen das (neue) Integerobjekt mit dem Wert 10 zugeordnet hat.
Wie oben gezeigt: bei veränderbaren Objekten geht das nicht - solange Du ihnen kein neues Objekt zuweist. Beachte, dass z.B. "list1 = list1 + [10]" zwar eine neue Liste liefert, diese aber nicht mehr das Objekt list1 ist:
Alle Klarheiten beseitigt?>>> l1 = [5]
>>> l1, id(l1)
([5], 13057200)
>>> l1.append(10)
>>> l1, id(l1)
([5, 10], 13057200)
>>> l1 = l1+[15]
>>> l1, id(l1)
([5, 10, 15], 13024032)
Grüße,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...