Seite 1 von 2
Klassenweite Variablen
Verfasst: Mittwoch 11. Mai 2005, 22:20
von freq.9
Wie bekomme ich Klassenweiter Variablen hin? Also ich will in jeder Funktion eine bestimmte Variable so nutzen können. In PHP ists ja so, dass ich das mit $this mache aber in Python bin ich soweit noch nicht, dass ich das weiss und in der Doc finde ich nun auch nichts passendes.
Wie ich es meine:
Code: Alles auswählen
class Foo:
def __init__(self):
moep = "Hallo"
def __del__(self):
print moep
Wenn ich das so machen würde, bekomme ich folgende Meldung:
Exception exceptions.NameError: "global name 'moep' is not defined" in <bound me
thod Foo.__del__ of <__main__.Foo instance at 0x009C6800>> ignored
Verfasst: Mittwoch 11. Mai 2005, 22:36
von CM
Hoi,
Die Klassenkonzepte von PHP und Python ähneln sich durchaus. In PHP (und C++) gibt es "this", in Python "self". Das ist zwar systaktisch und semantisch ein bißchen was anderes - und deshalb würde ich Dir schon noch empfehlen die Pythondoku in dem Punkt etwas genauer anzuschauen -, aber prinzipiell geht das so:
Code: Alles auswählen
class Foo:
def __init__(self):
self.bar = 'Hallo'
def __repr__(self):
return self.bar
x = Foo()
print x
... sollte brav "Hallo" sagen, denn mit "self" kannst Du innerhalb einer Klasse auf die klasseneigenen Parameter zugreifen. Von globalen Variablen würde ich hierbei aber nicht gebrauch machen.
Gruß,
Christian
Verfasst: Mittwoch 11. Mai 2005, 22:44
von freq.9
Jau cool danke funktioniert. Hatte ich doch eigentlich am Anfang so gemacht, oder nicht!? Naja nun gehts

Danke.
Hatte schon auf ner anderen Seite im Netz was über "global" gelesen aber als ich das getestet hab, habe ich immer "None" statt meinen Wert ausgegeben bekommen.
Verfasst: Mittwoch 11. Mai 2005, 22:49
von freq.9
Achso ne Frage hätt ich dann doch noch dazu:
Code: Alles auswählen
class Foo:
def __init__(self):
self.moep = "Hallo"
def __del__(self):
self.moep = self.moep, " Welt"
Das geht nicht. Wie wäre das denn richtig?
Verfasst: Mittwoch 11. Mai 2005, 22:54
von CM
Nein, Du hattest am Anfang auf "moep" zugegriffen, das aber in __del__ nicht bekannt war.
Zur letzten Frage: Was bitte ist "Welt"?
Aber die Beantwortung überlasse ich jetzt anderen.
Gute Nacht,
Christian
PS Wir mal einen Blick
hier hinein.
Verfasst: Mittwoch 11. Mai 2005, 22:57
von freq.9
CM hat geschrieben:Nein, Du hattest am Anfang auf "moep" zugegriffen, das aber in __del__ nicht bekannt war.
Zur letzten Frage: Was bitte ist "Welt"?
Aber die Beantwortung überlasse ich jetzt anderen.
Gute Nacht,
Christian
PS Wir mal einen Blick
hier hinein.
Ich möchte "Welt" an den String in moep anhängen. In PHP sähe das wie folgt aus:
Code: Alles auswählen
$moep = "Hallo";
$moep = $moep . " Welt";
print $moep; // würde "Hallo Welt" ausgeben
Verfasst: Donnerstag 12. Mai 2005, 00:47
von rayo
hi
Dann geh doch in der Doku nachlesen, wie man
Strings zusammenkettet.
Allgemein ist es eine gute Idee das
Tutorial mal zu durchlesen.
Gruss
Verfasst: Donnerstag 12. Mai 2005, 06:21
von freq.9
rayo hat geschrieben:hi
Dann geh doch in der Doku nachlesen, wie man
Strings zusammenkettet.
Allgemein ist es eine gute Idee das
Tutorial mal zu durchlesen.
Gruss
So nun hab ich mich mal registriert.
Also scheinbar liegt mein Fehler nicht bei der Verkettung von zwei "Strings" sondern, dass ich einmal ein "Tuple" und ein "String" zusammenfügen will und das scheinbar nicht mal eben so geht.
Also hier mal mein Script:
Code: Alles auswählen
class RSS:
def __init__(self):
self.node_count = 0
self.nope_opened = -1
self.required = [-1, -1, -1]
self.xml = "<?xml version="1.0"?>\n <rss version="2.0">\n <channel>\n"
def __del__(self):
""" In die *.xml Datei schreiben """
self.xml += " </channel>\n </rss>\n"
print self.xml
def addNode(self, obj):
self.node_opened = 1
self.node_count += 1
if self.node_count == 1:
self.xml += "\n <!-- Items -->\n", obj.get()
else:
self.xml += obj.get()
def addLanguage(self):
return ElementWithValue('language')
class ElementWithValue:
def __init__(self, element, sub = -1):
if sub != -1:
self.xml = " <", element
else:
self.xml = " <", element
def addAttribute(self, key, value):
self.xml += " ", key, "="", value, """
def get(self):
return self.xml, " />\n"
x = RSS()
x2 = x.addLanguage()
x2.addAttribute("foo", "bar")
x.addNode(x2)
Und wenn ich das so ausführe wie es jetzt ist, dann bekomme ich dies ausgegeben:
Traceback (most recent call last):
File "C:\Server\Apache2\Python\Lib\rss\rss.py", line 56, in ?
x.addNode(x2)
File "C:\Server\Apache2\Python\Lib\rss\rss.py", line 33, in addNode
self.xml += "\n <!-- Items -->\n", obj.get()
TypeError: cannot concatenate 'str' and 'tuple' objects
<?xml version="1.0"?>
<rss version="2.0">
<channel>
</channel>
</rss>
Btw: Wie gesagt sind das noch die anfänge. Ich versuche lediglich eine Bibliothek aus PHP in Python zu schreiben. So hab ich immer einen kleinen vergleich.
Und die Doku hab ich nun schon seit 2 Tagen durchgehen offen. Ich suche da wohl schon nur leider bin ich nicht so unbedingt der Profi in der englischen Sprache und von daher finde ich so manch Sachen nicht mal eben so. Sorry :!
Verfasst: Donnerstag 12. Mai 2005, 07:33
von CM
Hoi
Du machst gleich mehrere Denkfehler:
1.) Wozu brauchst Du __del__? Denkst Du an einen Destruktor? Brauchst Du (hier) gar nicht. Sowie Python keine Referenz mehr auf ein Objekt findet, wird der Speicher automatisch freigegeben. Wenn Du zusätzlich __del__ definierst, dann wird diese Funktion ausgeführt bevor die Referenz freigegeben wird. Es ist quasi ein finales Statement: "Wenn Du, mein Pythonskript, schon aufräumen willst - dann mache vorher noch dieses, das und jenes!"
2.) Was Du hier willst, so scheint es mir, ist in eine Datei schreiben? Aber Du hast gar keinen Stream geöffnet!
3.) Frage dich mal was obj ist. Dazu schau mal was passiert wenn Du obj.get() auszudrucken versuchst. Du wirst eben ein Objekt sehen (hier x2). Aber da Du Python nicht erzählt hast, was es damit machen soll, z. B. den String eines Element rausgeben, hat es diese Info nicht und versucht das ganze x2-Objekt mit x zu verketten - das geht natürlich nicht. Was Du - vielleicht möchtest - ist self.xml mit obj.xml zu verketten. Das allerdings sollte funktionieren.
Gruß,
Christian
PS Schau mal weiter unten in das Forum zu den Tutorials - dort gibt es auch eine Reihe von Links auf deutschsprachige Seiten.
Verfasst: Donnerstag 12. Mai 2005, 09:38
von jens
Code: Alles auswählen
self.xml = "<?xml version=\"1.0\"?>\n <rss version=\"2.0\">\n <channel>\n"
Das geht einfacher:
Code: Alles auswählen
self.xml = '<?xml version="1.0"?>\n <rss version="2.0">\n <channel>\n'
String zu erweitern geht mit "+" nicht mit ","
Verfasst: Donnerstag 12. Mai 2005, 14:05
von freq.9
Zu den Denkfehlern:
1) Das mit dem Destruktor, da hattest du Recht. Ich hätte nun mal gedacht, dass es ein Destruktor ist. Wobei in der Doc folgendes steht:
3.3.1 Basic customization hat geschrieben:__del__( self)
Called when the instance is about to be destroyed. This is also called a destructor.
2) Ich bin grade dabei mich mit Python zu beschäftigen und werde mich erst mit dem "in Dateien schreiben" befassen, sobald ich das XML Konstrukt per print richtig ausgeben kann. Vorher brauche ich ja auch noch nicht in eine Datei zu schreiben.
3) Aber wieso gibt denn obj.get() das Objekt wieder?
obj ist doch die Instanz der
class ElementWithValue. Und in Funktion get() in ElementWithValue soll doch self.xml zurückgegeben werden. Geht doch in PHP etc. auch so!?
--> Tutorials: Jau werd ich mir mal angucken. Hab mir bisher nur dieses eine Forum angesehen.
@ jens:
Hmmm. Bei mir kam da einmal ne Fehlermeldung und da dachte ich, dass das nicht geht. Muss wohl an was anderem gelegen haben, wenn es doch geht.
erweitern mit "+", aber für was ist dann ","?
Verfasst: Donnerstag 12. Mai 2005, 15:11
von CM
Hi,
vielleicht solltest Du Dir doch erst mal das Tutorial durchlesen, bevor Du in Details einsteigst?
Zu __del__: Lies Dir mal den Rest dazu durch.
Zu Dateien: Das ist in Python so einfach (verglichen mit C oder PHP), das kannst Du im Tutorial mal eben so mitnehmen und verstehen.
Zu Deiner get()-Methode: Diese Methode ist eine von ElementWithValue und nicht von RSS! Und x2 ist eine Instanz von RSS und RSS kennt get() nicht. Auch PHP kennt diesen Unterschied

.
Zu + vs. ,: Das steht auch im Tutorial. Was Du an manchen Stellen machst ist tuple von (Rückgabe-)Werten erzeugen und diese dann noch verketten. Das kann man machen, aber ich glaube, das ist nicht was Du willst.
Zu dem "Englisch-Problem": Wie hast Du denn PHP gelernt? Also, wenn alle Stricke reißen, müßtest Du halt in ein deutschsprachiges Buch investieren.
Gruß,
Christian
PS Es gibt auch das eine oder andere xml-Modul für Python. Vielleicht könntest Du das nutzen?
Verfasst: Donnerstag 12. Mai 2005, 18:12
von Leonidas
Und bitte, bitte, bitte tu zwischen die Zuweisung (zB: self.xml = '<?xml version="1.0"?>\n <rss version="2.0">\n <channel>\n') nur ein Leerzeichen davor und danach. Das hat zwar keine Bedeutung für Python, wohl aber für die Programmierer die deinen Code lesen. und das ist unpraktisch und verwirrt.
Verfasst: Donnerstag 12. Mai 2005, 20:26
von jens
CM hat geschrieben:Zu dem "Englisch-Problem": Wie hast Du denn PHP gelernt? Also, wenn alle Stricke reißen, müßtest Du halt in ein deutschsprachiges Buch investieren.
Als Einstieg ist allerdings schon einiges da s.
http://www.python-forum.de/viewtopic.php?p=13877#13877
Wobei natürlich ein umfassendes Buch/Seite wir z.B. selfPHP schon nicht schlecht wäre

An der original Doku stört mich am meißten, das es einfach zu wenige Beispiele enthält...
Verfasst: Donnerstag 12. Mai 2005, 20:37
von mawe
jens hat geschrieben:
An der original Doku stört mich am meißten, das es einfach zu wenige Beispiele enthält.
Dafür gibts ja hier die Codesnippets und das Showcase

Verfasst: Donnerstag 12. Mai 2005, 21:55
von BlackJack
Jetzt hat ihm immer noch niemand seine Ausgangsfrage beantwortet. Klassenweite Variablen bekommt man, in dem man sie auf der "Ebene" der Klasse definiert und über den Klassennamen referenziert:
Code: Alles auswählen
class Spam:
counter = 0
def __init__(self):
Spam.counter += 1
print 'Es wurden schon %d Spam-Instanzen erzeugt' % Spam.counter
Aber er wollte ja offensichtlich Instanzvariablen haben.
Ein Programm aus einer anderen Sprache in eine neue mehr oder weniger 1:1 übersetzen zu wollen produziert übrigens in vielen Fällen ziemlich hässlichen Quelltext. Wenn die Sprachen alle gleich funktionieren würden und die gleichen Idiome und Muster verfolgen würden, dann bräuchte man ja gar nicht erst verschiedene Sprachen.
Verfasst: Donnerstag 12. Mai 2005, 22:12
von CM
Der Punkt geht an Dich - trotz Haarspalterei

.
Verfasst: Freitag 13. Mai 2005, 11:53
von Gast
hallo zusammen,
na ich weiss nicht, ob das beispiel von BlackJack gut ist, gut in dem sinne es nachzuahmen und darauf aufzubauen. klassenvariablen würde ich im konstruktor so nicht verändern.
besonders wenn es später um vererbung geht, kann das ungewünschte effekte bringen.
Bsp:
BlackJack's Variante, dann meine:
Code: Alles auswählen
>>> class Spam:
counter=0
def __init__(self):
Spam.counter += 1
print 'Es wurden schon %d Spam-Instanzen erzeugt' % Spam.counter
>>> spam=Spam()
Es wurden schon 1 Spam-Instanzen erzeugt
>>> Spam.counter
1
>>> spam.counter
1
>>> class Spam:
counter=0
def __init__(self):
self.counter += 1
print 'Es wurden schon %d Spam-Instanzen erzeugt' % self.counter
>>> spam=Spam()
Es wurden schon 1 Spam-Instanzen erzeugt
>>> Spam.counter
0
>>> spam.counter
1
>>>
will sicher nicht klugscheissen, sondern habe mir nur mal meine gedanken gemacht.
lg,
rolgal
Verfasst: Freitag 13. Mai 2005, 17:47
von Leonidas
Aber das Funktioniert doch so nicht:
Code: Alles auswählen
>>> Spam()
Es wurden schon 1 Spam-Instanzen erzeugt
>>> Spam()
Es wurden schon 1 Spam-Instanzen erzeugt
Es sollte aber zwei zeigen, insofern würde ich BlackJacks Variante nehmen, wenn ich will dass alle Klasseninstanzen die Variable sich teilen.
Verfasst: Freitag 13. Mai 2005, 17:59
von Gast
hi leonidas,
Aber das Funktioniert doch so nicht:
stimmt schon was du sagt, ich hatte an ein bsp. von mir gedacht, das ich programmiert habe und dachte, dass ich da in teufelsküche gekommen wäre,......naja dann wurde mir wieder klar, dass python ja soviele möglichkeiten bietet etwas anzugehen, dass ich nur einiges ändern müsste und es würde auch wieder laufen,
wahrscheinlich war es für mich einfach etwas seltsam zu sehen, dass eine klassenvariable im konstruktor der eine instanz erstellt in dieser weise verändert wird.
lg
rolgal