Seite 1 von 1

Sichtbarkeit von Variablen über Modulgrenzen

Verfasst: Dienstag 19. Januar 2010, 11:34
von achilles_69
Hallo liebes Forum,

ich habe ein Problem mit der Sichtbarkeit von Variablen: Ich habe drei verschiedene Module:
+ QueryStempelliste.py
+ SelectStempellisteViewDelegate.py
+ DialogSelectStempelliste.py

(Code-Ausschnitte habe ich unten angehängt.

Im Modul QueryStempelliste definiere ich einige Variablen (ID_STEMPEL, TYP, BEZEICHNUNG, ...), die ich als
Index für den Zugriff auf Elemente einer Liste mit meinen Daten brauche.
Das lustige ist nun, dass ich im Modul SelectStempellisteViewDelegate diese Variablen benutzen kann (Methode paint()).
Im Modul DialogSelectStempelliste in der Methode result() erhalte ich jedoch beim Versuch, auf die Variable
QueryStempelliste.ID_STEMPEL zuzugreifen eine Fehlermeldung:
Traceback (most recent call last):
File "./DialogSelectStempelliste.py", line 140, in <module>
stempelliste = select.result()
File "./DialogSelectStempelliste.py", line 79, in result
id_stempel = selected_entry[QueryStempelliste.ID_STEMPEL].toInt()[0]
AttributeError: type object 'QueryStempelliste' has no attribute 'ID_STEMPEL'
Wenn ich statt

Code: Alles auswählen

id_stempel = selected_entry[QueryStempelliste.ID_STEMPEL].toInt()[0]
jedoch

Code: Alles auswählen

id_stempel = selected_entry[0].toInt()[0]
verwende, klappt alles wunderbar.

Jetzt bin ich ziemlich ratlos: warum kann ich in einem Modul auf die Variablen zugreifen, in einem anderen
aber nicht? Der Import ist doch derselbe...

Modul QueryStempelliste.py:

Code: Alles auswählen

from PyQt4 import QtCore, QtSql

from sw_exception_classes import DatabaseError, KeyNotFound, TypeNotSupported, \
        IndexOutOfRange

NUMBER_OF_FIELDS = 8
ID_STEMPEL, TYP, BEZEICHNUNG, VON, BIS, KW, JAHR, STATUS = range(NUMBER_OF_FIELDS)

class QueryStempelliste(object):
    ...
Modul SelectStempellisteViewDelegate.py:

Code: Alles auswählen

from select_stempelliste import QueryStempelliste
from PyQt4 import QtGui, QtCore

class SelectStempellisteViewDelegate(QtGui.QAbstractItemDelegate):
    def __init__(self):
        ...

    def paint(self, painter, option, index):
        ...
        painter.drawText(rahmen.x()+self.indent, rahmen.top() + 2 * \
                self.lineheight, QtCore.QString("KW %1/%2 vom %3 bis zum %4").\
                    arg(entry[QueryStempelliste.KW].toString()).\
                    arg(entry[QueryStempelliste.JAHR].toString()).\
                    arg(entry[QueryStempelliste.VON].toString()).\
                    arg(entry[QueryStempelliste.BIS].toString()))
Modul DialogSelectStempelliste.py:

Code: Alles auswählen

from select_stempelliste import QueryStempelliste, SelectStempellisteViewDelegate, \
        SelectStempellisteViewModel, SelectedStempelliste, AffectedFlight

from PyQt4 import QtGui, QtCore, QtSql
from ui_select_stempelliste import Ui_select_stempelliste as DlgSelectStempelliste

class DialogSelectStempelliste(QtGui.QDialog, DlgSelectStempelliste):
    def __init__(self, parent=None):
        ...

    def result(self):
        ...
        if self.result_list.currentIndex().isValid():
            selected_entry = self.result_list.currentIndex().data().toList()
            id_stempel = selected_entry[QueryStempelliste.ID_STEMPEL].toInt()[0]
            return SelectedStempelliste(id_stempel)


Verfasst: Dienstag 19. Januar 2010, 11:53
von mkesper
In Python brauchst du nicht für jede Klasse ein eigenes Modul, das stört eher!
Du versucht so etwas wie modulglobale Variablen zu verwenden, das sollte man eher nicht machen!
Wenn es sich um Klassen- / Instanzvariablen handelt, dann gehören diese in die Klasse.

Verfasst: Dienstag 19. Januar 2010, 12:06
von achilles_69
Das habe ich auch schon ausprobiert - nur habe ich das Problem dann vice versa, d.h. er kennt die Variable in DialogSelectStempelliste.py aber dafür in SelectStempellisteViewDelegate.py nicht mehr...

Ich werde aber noch mal ein bisschen basteln und Klassenvariablen verwenden. Könnte es vielleicht bei Klassenvariablen ein Problem geben, dass ich range(<VARIABLE>) verwende?

Entschuldigt bitte meine vielleicht etwas dumme Frage, aber ich bin effektiv erst seit ca. 6 Wochen bei Python und setzte gleich als erstes ein Projekt mit PyQt4 um...

Verfasst: Dienstag 19. Januar 2010, 12:21
von BlackJack
@achilles_69: Vielleicht hilft es ja schon Dich darauf hinzuweisen, dass Du in einem Modul das *Modul* `QueryStempelliste` verwendest -- das hat die Attribute, und in dem anderen Modul die *Klasse* QueryStempelliste, die hat die Attribute nicht. Und logischerweise hast Du das gleiche Problem wenn Du die Attribute vom Modul in die Klasse verschiebst, dann eben bloss anders herum.

Verfasst: Dienstag 19. Januar 2010, 12:28
von achilles_69
Ja, so etwas in der Art habe ich mir jetzt auch gedacht.
Großes Danke für die Hinweise, ich denke, jetzt komme ich alleine weiter...

Verfasst: Dienstag 19. Januar 2010, 12:33
von achilles_69
Doch etwas verfrüht - jetzt kommt mir doch eine Frage:

Sowohl im Modul SelectStempellisteViewDelegate.py als auch im Modul DialogSelectStempelliste.py referenziere ich doch mit

Code: Alles auswählen

QueryStempelliste.KW
[code]

bzw.

[code=py]
QueryStempelliste.ID_STEMPEL
[code]

Warum soll das jetzt in einem Fall eine Instanz- und im anderen Fall eine Klassen-Variable sein? Es gibt in keinem der Module eine Variable "QueryStempelliste"?

Verfasst: Dienstag 19. Januar 2010, 13:14
von gkuhl
Es gibt in Python keine Variabeln, sondern nur Namen/Bezeichner, die auf Objekte (Integer, Listen, Funktionen, Klassen...) zeigen.

Grüße
Gerrit

Verfasst: Dienstag 19. Januar 2010, 13:33
von mkesper
Wenn ich schon mehrere Module machen würde, (was wie gesagt, meist nicht nötig ist), dann würde ich die Verwirrung reduzieren, indem ich sie nicht gleich nenne wie die Klasse. Vielleicht wird es dann etwas klarer.

Verfasst: Dienstag 19. Januar 2010, 16:05
von Michael Schneider
Hallo,

falls Du es überlesen hast, schau Dir doch nochmal an, was BlackJack geschrieben hat.

Deine ursprüngliche Fehlermeldung sagt es auch:
"AttributeError: type object ..."
Hättest Du korrekterweise auf das Modulobjekt zugegriffen, dem das Attribut gefehlt hätte, dann hätte da folgendes gestanden:
"AttributeError: 'module' object ..."

Ferner hat auch mein Vorredner recht, dass Module nicht wie ihre Klassen genannt werden sollten. PEP-8 sieht für Module Kleinschreibung vor.

Gruß,
Michel

Verfasst: Dienstag 19. Januar 2010, 16:21
von achilles_69
Hättest Du korrekterweise auf das Modulobjekt zugegriffen, dem das Attribut gefehlt hätte, dann hätte da folgendes gestanden:
"AttributeError: 'module' object ..."
Ich hatte durchaus bemerkt, dass der Hund da begraben ist - ich wollte nur wissen, warum einmal das Modul und einmal die Klasse verwendet wurde, obwohl die Import-Anweisungen in den beiden Modulen gleich waren.

Ich habe meine Ordnerstruktur inzwischen umgekrempelt und jetzt funktioniert es auch.

@gkuhl:
Danke für die Info - ich bin noch neu bei Python und bin noch teilweise mit alten Konzepten verhaftet...