Auf Attribut einer importierenden Klasse zugreifen (gelöst)

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.
Benutzeravatar
erebus
User
Beiträge: 3
Registriert: Freitag 8. August 2008, 10:52

Auf Attribut einer importierenden Klasse zugreifen (gelöst)

Beitragvon erebus » Freitag 8. August 2008, 11:31

Hallo erstmal, ich mache hier mal meinen ersten Beitrag (leider in Form einer Frage).

Hintergrund (muss man nicht unbedingt lesen):

Ich schreibe gerade einen Fileserver (für mich persönlich), den ich schonmal so ähnlich mit PHP realisiert habe. Nun hat das alte PHP-Ding doch einige Verbesserungen nötig und da ich im Moment wenig Lust auf PHP habe, dachte ich, das ließe sich doch prima mit Python machen. Nach kurzer Einarbeitung in CherryPy (für die, die es nicht kennen, es ist ein Python-HTTP-Framework) konnte ich also Loslegen und habe auch schon gute fortschritte gemacht (Login-Funktionen, Benutzerverwaltung, Download von Dateien funktionieren schon). Aber ich stoße gerade als Neuling auf ein Problem, was eventuell zu lösen ist. Vielleicht habe ich dem Thema (ich bin autodidakt) ein bißchen zu wenig Aufmerksamkeit geschenkt.

Problemstellung:

Ich muss von einer importierten Klasse auf eine Klassenattribut der importierenden Klasse zugreifen. In meinem speziellen Fall geht es um Daten, die während eine Uploads (zum Server) über den laufenden Transfer gespeichert werden sollen (für einen Fortschirttsanzeige), der Prozess geht von einer importierten Klasse aus, soll die Daten aber in der importierenden Klasse ablegen, weil eine andere Funktion (diese ist eine Funktion der importierenden Klasse) während des Uploads diese Daten abfragen soll.

In der Grafik (siehe unten) hoffe ich zu verdeutlichen, was ich meine. Die Datei klasse1.py ist deshalb Teil eines Moduls, weil der eigentliche Code, der für ein Beispiel zu umfangreich ist, auch aus einem Modul importiert. Ich stelle das hier mal in einem Minimalbeispiel dar. Wie müsste ich also das Attribut "a" referenzieren um Zugriff darauf zu haben?

Bild

LG
erebus
Zuletzt geändert von erebus am Freitag 8. August 2008, 13:27, insgesamt 1-mal geändert.
BlackJack

Beitragvon BlackJack » Freitag 8. August 2008, 12:02

"Importierende Klassen" macht nicht viel Sinn. Klassen importieren nichts, das macht man mit der ``import``-Anweisung, und die kann zwar so ziemlich überall verwendet werden, wo man Anweisungen verwenden kann, aber das ist in der Regel am Anfang von Modulen.

Also ist die Frage was Du mit "importierender Klasse" eigentlich meinst?

Für Fortschrittsinformation bietet es sich an, der Funktion die die Arbeit verrichtet, eine Rückruffunktion mit zu geben, die sie in gewissen Abständen dann mit entsprechenden Fortschrittsdaten auf ruft.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Freitag 8. August 2008, 12:07

Böse. Das geht mit ein wenig Gefrickel zu Lösen, ist aber nicht schön.

http://effbot.org/zone/import-confusion.htm
Dort unter "recursive imports" ist dein Problem beschrieben.

Zur Kommunikation zwischen Thread könntest du z.B. Queues machen, aber lieber nicht mit Klassenattributen.
Benutzeravatar
erebus
User
Beiträge: 3
Registriert: Freitag 8. August 2008, 10:52

Beitragvon erebus » Freitag 8. August 2008, 12:16

@audax, danke, aber hat nicht geholfen.

ich habe jetzt:

klassentest.py:

Code: Alles auswählen

import klasse1
class Root():
   
   a = 500
   def __init__(self):
      x = klasse1.Klasse1()
      x.eineFunktion()
      print u'Nach der Veränderung eineFunktion() - klassentest.Root:', Root.a

if __name__ == '__main__':
   Root()


und

klasse1.py:

Code: Alles auswählen

class Klasse1():
   test = 100

   def eineFunktion(self):
      import klassentest
      klassentest.Root.a = Klasse1.test
      print u'Nach der Veränderung durch eineFunktion() - klasse1.Klasse1:', klassentest.Root.a


Ausgabe ist:
[code=]Nach der Veränderung durch eineFunktion() - klasse1.Klasse1: 100
Nach der Veränderung eineFunktion() - klassentest.Root: 500[/code]

Anscheinend sind die Klassen "klassentest.Root" (von Klasse1 aus) und "Root" (von Klasse Root aus bzw. nicht aus klasse1.py aus) verschieden. Ich habe also eine lokale Version von Root in Klasse1. Das will ich aber nicht, ich möchte auf die Klasse Root zugreifen können, von der aus klasse1 importiert wird. :-( Ich will das die Ausgabe so aussieht:

[code=]Nach der Veränderung durch eineFunktion() - klasse1.Klasse1: 100
Nach der Veränderung eineFunktion() - klassentest.Root: 100[/code]

EDIT (Gelöst) : :twisted:

Hab anscheinend eine Lösung gefunden. Vielleicht geht es noch eleganter:

klassentest.py:

Code: Alles auswählen

import klasse1
class Root():
   
   a = 500
   def __init__(self):
      x = klasse1.Klasse1()
      x.eineFunktion(Root)
      print u'Nach der Veränderung eineFunktion() - klassentest.Root:', Root.a

if __name__ == '__main__':
   Root()


klasse1.py:

Code: Alles auswählen

class Klasse1():
   test = 100

   def eineFunktion(self,xclass):
      import klassentest
      xclass.a = Klasse1.test
      print u'Nach der Veränderung durch eineFunktion() - klasse1.Klasse1:', xclass.a


Mann muss also eine Referenz auf die "Ober"-Klasse (nicht im Sinne von Vererbung) mitgeben, oder gibt es noch eine möglichkeit um an eine Referenz auf Root zu kommen?
bastian.weber
User
Beiträge: 15
Registriert: Montag 4. August 2008, 23:30
Wohnort: Dresden

Beitragvon bastian.weber » Montag 11. August 2008, 21:50

Ich glaube richtig professionell würde man es mit Threads machen, aber da kenne ich mich auch nicht aus.

Jedenfalls bin ich der Meinung, dass in Deinem letzten (also funktionierenden) Codebeispiel der Import von klassentest in eineFunktion() unnötig ist.

Vielleicht solltest Du auch darüber nachdenken, in der Klasse Root ein Kommunikationsobjekt anzulegen, welches Du dann rumreichen kannst. Das finde ich besser, als gleich die ganze Klasse zu übergeben nur weil dort ein Wert gesetzt werden soll. das widerspricht imo dem Paradigma, dass ein Objekt nur auf die Daten und Funktionalität Zugriff haben sollte mit denen es sinnvoll Arbeiten kann.

Wer ist online?

Mitglieder in diesem Forum: Whitie