Seite 1 von 2
Klassenattributte umbn(__init__ aufruf...was ruft er da auf)
Verfasst: Montag 18. Juni 2007, 12:26
von grandma
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?
Verfasst: Montag 18. Juni 2007, 12:29
von birkenfeld
Ohne Code wohl kaum...
Verfasst: Montag 18. Juni 2007, 12:38
von grandma
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 = []
aufruf wie gesagt mit chart = MyChart()
Verfasst: Montag 18. Juni 2007, 13:18
von mawe
Also bei mir kommt da keine Fehlermeldung. Ich wüsste auch nicht warum.
Verfasst: Montag 18. Juni 2007, 13:26
von grandma
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)
Re: __init__ aufruf...was ruft er da auf?
Verfasst: Montag 18. Juni 2007, 13:31
von Y0Gi
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??
Das verrät der komplette Traceback.
Möglicherweise ist da eine veraltete Version im Spiel.
Verfasst: Montag 18. Juni 2007, 13:37
von grandma
Ich habe eigentlich gar keinen Traceback, das mit der Exception in ein File schreiben ist auch nur einen Notlösung um überhaupt eine Fehlermeldung zu kriegen.
Verfasst: Montag 18. Juni 2007, 14:26
von grandma
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)
Verfasst: Montag 18. Juni 2007, 14:28
von Sr4l
Code: Alles auswählen
import sys
import traceback
"".join(
traceback.format_exception(
sys.exc_type,sys.exc_value,sys.exc_traceback))
Wenn du den Inhalt dieses Code Mixes in die Datei schreibst bekommst du ein 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.
Verfasst: Montag 18. Juni 2007, 20:57
von rolgal_reloaded
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 = []
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.
LG
rolgal_reloaded
Verfasst: Montag 18. Juni 2007, 23:30
von BlackJack
Dann teilen sich alle Objekte dieses Typs die Attribute. Das ist *sehr* wahrscheinlich nicht das gewünschte Verhalten.
Verfasst: Dienstag 19. Juni 2007, 06:28
von rolgal_reloaded
BlackJack hat geschrieben:Dann teilen sich alle Objekte dieses Typs die Attribute. Das ist *sehr* wahrscheinlich nicht das gewünschte Verhalten.
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?
Verfasst: Dienstag 19. Juni 2007, 06:44
von grandma
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.
Verfasst: Dienstag 19. Juni 2007, 07:04
von rolgal_reloaded
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
>>> 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
Verfasst: Dienstag 19. Juni 2007, 07:05
von Michael Schneider
rolgal_reloaded hat geschrieben:BlackJack hat geschrieben:Dann teilen sich alle Objekte dieses Typs die Attribute. Das ist *sehr* wahrscheinlich nicht das gewünschte Verhalten.
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?
Hi,
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
Verfasst: Dienstag 19. Juni 2007, 07:14
von rolgal_reloaded
@Michael
Ich versteh das schon, nur wie oben gezeigt, lassen sich die Werte der einzelnen Instanzen ohne Einfluss aufeinander ändern.
LG
r_r
Verfasst: Dienstag 19. Juni 2007, 07:22
von grandma
Ok es ist ein Zopeproblem...
Ich habe das File komplett gelöscht und trotzdem wird noch drauf zugegriffen, ich habe keine Ahnung wo er das noch hernimmt.
Mal im Zopeforum nachfragen...
Danke an alle hilfbereiten hier
Verfasst: Dienstag 19. Juni 2007, 07:27
von Michael Schneider
Hallo Rolgal!
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:
Ja, es geht darum, ob prinzipiell dasselbe Objekt an die Instanz weitergegeben wird, oder gleich eine Kopie - also ein anderes Objekt.
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)
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:
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])
Das kann erwünscht sein, aber auch nicht.
Grüße,
Michael
Verfasst: Dienstag 19. Juni 2007, 07:42
von rolgal_reloaded
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
Oder gibt es Fälle wo das wie vom Autor des Threads gezeigt wird besser ist?
LG
rolgal_reloaded
Verfasst: Dienstag 19. Juni 2007, 07:44
von Michael Schneider
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
Hi rolgal,
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:
>>> 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)
Alle Klarheiten beseitigt?
Grüße,
Michel