Sichtbarkeit von Variablen über Modulgrenzen

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.
Antworten
achilles_69
User
Beiträge: 21
Registriert: Dienstag 31. März 2009, 14:05
Wohnort: Bielefeld

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)

Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

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.
achilles_69
User
Beiträge: 21
Registriert: Dienstag 31. März 2009, 14:05
Wohnort: Bielefeld

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...
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.
achilles_69
User
Beiträge: 21
Registriert: Dienstag 31. März 2009, 14:05
Wohnort: Bielefeld

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...
achilles_69
User
Beiträge: 21
Registriert: Dienstag 31. März 2009, 14:05
Wohnort: Bielefeld

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"?
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Es gibt in Python keine Variabeln, sondern nur Namen/Bezeichner, die auf Objekte (Integer, Listen, Funktionen, Klassen...) zeigen.

Grüße
Gerrit
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

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.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

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
Diese Nachricht zersört sich in 5 Sekunden selbst ...
achilles_69
User
Beiträge: 21
Registriert: Dienstag 31. März 2009, 14:05
Wohnort: Bielefeld

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...
Antworten