Objektvariablen in __init__ werden nicht gesetzt.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
MikeScript
User
Beiträge: 10
Registriert: Montag 21. September 2009, 19:24

Hallo.

Mein erstes Anliegen in diesem Forum führt zu einer merkwürdigen Frage: Kann der Konstruktor keine Objektvariablen mit Werten füllen?

Sowohl hier: http://www.python-kurs.eu/klassen.php
als auch hier: http://docs.python.org/reference/datamo ... thod-names
sieht es so aus als ob folgendes gelingen sollte:

Code: Alles auswählen

class Template:

    def __init__(self, tpl):
        '''
        Constructor
        '''
        self._values = {}
        self.__tpl = tpl
        f = open(tpl, "r")
        self.htmlText = f.read()
        f.close
Allerdings bleibt sowohl "htmlText" als auch "__tpl" leer, was ich durch mehrere Versuche dies auszugeben gesehen habe:

Code: Alles auswählen

def __str__(self):
        return self.__tpl
- Aufgerufen mit req.write(str(eine_instanz))

Das ganze läuft unter Py2.5 und ich hoffe mir kann jemand dieses Verhalten erklären.

Gruß,
Zod
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

In [5]: class Template(object):
   ...:     def __init__(self, template):
   ...:         self.values = {}
   ...:         self.tpl = template
   ...:         self.html_text = "abs"
   ...:
   ...:

In [6]: t = Template("xs")

In [7]: t.tpl
Out[7]: 'xs'

In [8]: t.values
Out[8]: {}

In [9]: t.html_text
Out[9]: 'abs'
Wie du siehst funktioniert ``__init__`` (Konstruktor ist falsch, da der in Python 2-stufig ist, ``__new__`` und ``__init__``)

Daneben solltest du mal PEP8 lesen und _einen_ Unterstrich fuer "private" Namen nutzen. Das Konzept gibt es in Python nicht, sondern nur die Konvention den Praefix `_` zu nutzen.

Du solltest mal sagen, wie du denn Exemplare von ``Template`` erzeugst.
MikeScript
User
Beiträge: 10
Registriert: Montag 21. September 2009, 19:24

Ok. Danke für die Coding-Standards.
Ich merke gerade, dass die Ausgabe oder Übersetzung von Python scheinbar gecached wird. Zumindest scheint es so, denn wenn ich den Quelltext ändere, ändert sich nichts an der Ausgabe.

Das ganze läuft auf Apache 2.2.13 mit mod_python für Py2.5. vom Apache aus habe ich Cache-Control so herunter gesetzt, dass nichts gecached wird.

Eine Frage noch hinterher. Es sollen __setattr__ und __getattr__ verwendet werden. Wie erreicht man es, dass trotzdem die Objektvariablen beschrieben werden, sofern sie existieren?

__setattr__ scheint immer Aufgerufen zu werden im gegensatz zu __getattr__ http://www.python.org/doc/2.5.2/ref/att ... ccess.html

Code: Alles auswählen

class Template(object):
    '''
    classdocs
    '''
    
    _values = {}
    _tpl = ""

    def __init__(self, tpl):
        '''
        Constructor
        '''
        self.text = ""  #soll __setattr__ nutzen
        self._values = {}  # soll _values nutzen
        self._tpl = ""  # soll _tpl nutzen
        
        self._tpl = tpl
    
    def __getattr__(self, name):
        return self._values[name]
    
    def __setattr__(self, name, value):
        self._values[name] = value
        
    def __str__(self):
        return str(self._values)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

MikeScript hat geschrieben:Das ganze läuft auf Apache 2.2.13 mit mod_python für Py2.5. vom Apache aus habe ich Cache-Control so herunter gesetzt, dass nichts gecached wird.
mod_python hat den denkbar schlechtesten Ansatz um Python auszufuehren. AFAIK sind mod_wsgi und mod_fcgi besser. Am besten erstellst du einen neuen Thread fuer das Problem, damit das auch die Leute lesen, die sich damit auskennen.
MikeScript hat geschrieben:Eine Frage noch hinterher. Es sollen __setattr__ und __getattr__ verwendet werden. Wie erreicht man es, dass trotzdem die Objektvariablen beschrieben werden, sofern sie existieren?

Was meinst du mit Objektvariablen? Die Instanzvariablen? Oder die in deinem values-Dict? IMHO sollte beides immer passieren (in deinem Fall letzteres)
MikeScript hat geschrieben:__setattr__ scheint immer Aufgerufen zu werden im gegensatz zu __getattr__ http://www.python.org/doc/2.5.2/ref/att ... ccess.html
Fuer newstyle-Klassen - erben von ``object`` - gibt es ``__getattribute__``, dort ist der Aufruf garantiert. http://docs.python.org/reference/datamo ... ic-classes
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

cofi hat geschrieben:Daneben solltest du mal PEP8 lesen und _einen_ Unterstrich fuer "private" Namen nutzen. Das Konzept gibt es in Python nicht, sondern nur die Konvention den Praefix `_` zu nutzen.
Warum hat man eigentlich in Py3 mit dieser Katatrophenkonvention nicht mal aufgeräumt? Hat irgendwie so ein halbfertigen Workarround smell. private, public,protected würden der Sprache nicht schaden.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

hendrikS hat geschrieben:Warum hat man eigentlich in Py3 mit dieser Katatrophenkonvention nicht mal aufgeräumt? Hat irgendwie so ein halbfertigen Workarround smell. private, public,protected würden der Sprache nicht schaden.
Und welchen Mehrwert haben die Schluesselworte? IMHO ist das nur unnoetiger Clutter und ich finde nicht, dass man sich da an anderen Sprachen orientieren muss, schon gar nicht wenn sie nicht dynamisch sind und ganz anderen Konzepten folgen.

Ohne tiefgreifende Aenderungen am Objektmodell, macht man Versprechungen die man nicht halten kann.
BlackJack

@hendrikS: Vielleicht weil es keine Katastrophenkonvention ist, und viele der Meinung sind, dass insbesondere ``private`` der Sprache durchaus schaden kann. Ich habe bisher nur einmal, bei einer Mixin-Klasse, doppelte führende Unterstriche benötigt. Ansonsten reicht mir der dezente Hinweis `_spam` vs. `spam` völlig aus. ``private`` würde ich als Katastrophe ansehen, und das wäre dann ja noch nicht einmal mehr eine Konvention.
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Die Schlüsselworte stellen sicher, dass Objekte ein eindeutiges Interface haben. Dies ist vermutlich auch die Intension.
Kann mir nicht erklären, was an private schädlich sein soll.
Welchen Mehrwert haben Unterstriche? Keinen, sollte man nicht evtl.die Konvention kennen. Und selbst dann unterbinden sie nichts.
Alle OO Sprachen, die ich außer Python noch kenne (C++,C#,Ruby,Java) haben das. Nur Python macht darum einen Bogen. Ist mir schleierhaft.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hendrikS hat geschrieben:Die Schlüsselworte stellen sicher, dass Objekte ein eindeutiges Interface haben.
Inwiefern? Du verbietest doch nur den direkten Zugriff auf ein Attribut... was ist da der Mehrwert?

Das "eindeutig" klingt eher nach starker Typisierung...
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn es einem wirklich wichtig ist, dass ein Attribut unveränderbar ist, ließe sich doch auch sowas machen:

Code: Alles auswählen

In [54]: class Foo(object):
   ....:     @property
   ....:     def protected_value(self):
   ....:         return 'you can not change me'
   ....:     
   ....:     

In [55]: foo = Foo()

In [56]: foo.protected_value
Out[56]: 'you can not change me'

In [57]: foo.protected_value = 'but i want to'
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/home/sebastian/<ipython console> in <module>()

AttributeError: can't set attribute

In [58]: del foo.protected_value
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/home/sebastian/<ipython console> in <module>()

AttributeError: can't delete attribute
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich glaube, was hendrikS meint ist, dass z.B. ein `dir()` "geschützte" Attribute nicht ausgeben soll, damit der Nutzer einer Klasse nicht verwirrt ist, sondern nur das angezeigt bekommt, was er verwenden soll.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

hendrikS hat geschrieben:Alle OO Sprachen, die ich außer Python noch kenne (C++,C#,Ruby,Java) haben das. Nur Python macht darum einen Bogen. Ist mir schleierhaft.
Ja, genau. Warum sind nicht gleich alle Sprachen wie Java? ^^

Wenn du nicht erklären kannst, was an private schädlich ist, dann erkläre doch mal die Vorteile. Aber bitte nicht solche lächerlichen Sachen wie "Schutz des Programmierers vor sich selbst", "bessere Übersicht" oder "einfacher für Anfänger". Erstere lassen sich genauso über Konvention regeln und letzteres ist kein wirkliches Argument bei ernsthafter Softwareentwicklung.
Das Leben ist wie ein Tennisball.
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Den Vorteil und der Sinn des ganzen steht im zweiten Posting zu dem Thema ganz oben. Saubere Schnittstellen sind in der Softwareentwicklung nun mal das A & O. Und eigentlich nicht nur in der Softwareentwicklung.
Sonst würde man ja auch nicht auf die Idee kommen sogar eine jämmerliche PEP Unterstrichkonvention zu definieren.
... die man mit sprachlichen Mitteln in den Skat drücken könnte.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

hendrikS hat geschrieben:Welchen Mehrwert haben Unterstriche? Keinen, sollte man nicht evtl.die Konvention kennen. Und selbst dann unterbinden sie nichts.
Sie dokumentieren, genauso wie es private auch tut, nur dass man sich bei private anstrengen muss Mist zu bauen. Andererseits erlaubt einem ein offener Zugriff u.U. mehr Flexibilität. Die Frage was jetzt besser ist führt nur zu sinnlosen philosophischen Diskussionen die zu ähnlich ergiebigen Ergebnissen führen, wie die Diskussion dynamische vs. statische Typisierung. Es sind einfach verschiedene Philosophien, man mag sie mögen oder nicht.
Alle OO Sprachen, die ich außer Python noch kenne (C++,C#,Ruby,Java) haben das. Nur Python macht darum einen Bogen. Ist mir schleierhaft.
Dann kennst du kein Smalltalk, um mal ein Gegenbeispiel zu nennen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hendrikS hat geschrieben:Den Vorteil und der Sinn des ganzen steht im zweiten Posting zu dem Thema ganz oben.
Meinst Du da Dein eigenes 2. Posting?
hendrikS hat geschrieben: Saubere Schnittstellen sind in der Softwareentwicklung nun mal das A & O.
Dann erkläre doch bitte noch mal, inwiefern ein "private"-Mechanismus Schnittstellen definiert?
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Hyperion hat geschrieben:Dann erkläre doch bitte noch mal, inwiefern ein "private"-Mechanismus Schnittstellen definiert?
Nomen est omen würde ich mal so salopp sagen. Oder gibt es da noch mehr zu erklären?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

hendrikS hat geschrieben:
Hyperion hat geschrieben:Dann erkläre doch bitte noch mal, inwiefern ein "private"-Mechanismus Schnittstellen definiert?
Nomen est omen würde ich mal so salopp sagen. Oder gibt es da noch mehr zu erklären?
Tja, mir will das so nicht in den Kopf, wie "private" helfen soll, ein "eindeutiges Interface" zu schaffen. Wieso ist denn etwas ohne private schlechter? Vielleicht kannst Du da mal ein Beispiel geben?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Der einzige Nutzen von Qualifiern ist es, den Zugriff zu dokumentieren, darueber hinaus schafft es nur noch Huerden, fuer den Fall, dass man die Beschraenkung umgehen muss, zB fuer Tests etc.

Das gleiche leistet aber auch eine Konvention. Dass man vom Compiler bei Qualifiern auf die Finger geklopft bekommt, ist ein netter Nebeneffekt, aber das kann man auch mit Tools wie Pylint usw. bewerkstelligen, evtl gibt es auch Interesse solche Warnungen in den Interpreter einzubauen.
Hyperion hat geschrieben:Das "eindeutig" klingt eher nach starker Typisierung...
Statisch, nicht stark ;) Python hat eine starke Typisierung, aber eben auch eine dynamische.
hendrikS hat geschrieben:Welchen Mehrwert haben Unterstriche? Keinen, sollte man nicht evtl.die Konvention kennen. Und selbst dann unterbinden sie nichts.
Und wenn man Schluesselworte benutzt ist das besser? Entschuldige, aber die muss man genauso lernen, fuehrende Leerzeichen sind auch in anderen Sprachen als "reserviert" zu betrachten z.B. C/C++, insofern ist das Argument, dass man die Schluesselworte kennt, nichts wert. Dass man sich mit Idiomen und Konventionen vertraut macht, gehoert eben auch zum Lernen einer Sprache.

Und bitte trennt die Diskussion ab. Das ist wirklich sehr OT.
lunar

hendrikS hat geschrieben:Die Schlüsselworte stellen sicher, dass Objekte ein eindeutiges Interface haben.
Das ist doch – sei ehrlich – eine einzige große Illusion. Eine Eigenschaft eines Objekts wird nicht dadurch öffentlich, dass ich "public" davor schreibe. Das geschieht erst durch eine vernünftige Dokumentation dieser Eigenschaft. Nur Dokumentation schafft eine wirklich klare und eindeutige Schnittstelle.

Mit Dokumentation aber ist die Zugriffskontrolle ziemlich überflüssig. Man muss nicht extra "private" vor eine undokumentierte Eigenschaft schreiben, um sie als Implementierungsdetail zu kennzeichnen.

Zugriffskontrolle über Schlüsselworte funktioniert doch nur in der Theorie der Sprachdesigner. In der Praxis lässt sich reale, wirksame Zugriffskontrolle mit integrierter Dokumentation und einer unterstützenden Namenskonvention mindestens genauso gut, wenn nicht sogar besser umsetzen.

Edit: In C++ ist "private" sowieso eine Farce. Private Attribute einer Klassen können deren (zur Laufzeit einzig relevante) Binärschnittstelle beeinflussen. Insofern kann man gar nicht so ohne weiteres private Attribute zu einer Klassen hinzufügen, wenn man eine eindeutige Laufzeit-Schnittstelle nach außen hin erhalten will. Das Schlüsselwort ist somit eher kontraproduktiv, weil es etwas unterstellt, was faktisch so gar nicht richtig existiert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Darii hat geschrieben:
Alle OO Sprachen, die ich außer Python noch kenne (C++,C#,Ruby,Java) haben das. Nur Python macht darum einen Bogen. Ist mir schleierhaft.
Dann kennst du kein Smalltalk, um mal ein Gegenbeispiel zu nennen.
Oder JavaScript. Oder CLOS. Also kennst du hauptsächlich rote Äpfel, grüne Äpfel und gelbe Äpfel. Keine Birnen und von Bananen gar nicht erst zu sprechen. Daraus dann irgendwelche allgemeinen Aussagen zu machen scheint mir irgendwie zu voreilig.

Außerdem sehe ich nicht wo private Attribute das A & O von Softwareentwicklung sein sollten. Das würde implizieren, dass die Python-Software die existiert irgendwie davon abweicht, aber lustigerweise funktioniert die vorhandene Software durchaus gut.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten