execfile() und Namensräume

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
nfilus

Hallo,

bin relativ neu bei python und arbeite gerade an meinem ersten Projekt, bei dem ich auf ein Namensraumproblem gestossen bin. Ziel ist es Daten, die von einem externen Tool in python beschrieben werden einzulesen und auszuwerten. Diese Daten stehen in *.vec Dateien, die

Code: Alles auswählen

class filter(object):
    class a(my_class_a):
       ...
    class vector(object):
        def __init__(self, newdata):
            self.a = filter.a(newdata)

filter_list = [ filter.vector(...), filter.vector(...), .... ]
enthalten. Diese Daten sind dynamisch und sollten in einer Datei bleiben, um die Beschreibung konsistent zu halten. Jetzt das Programm und Problem:
testVector.py (Hauptmodul)

Code: Alles auswählen

from vectorTest import *
execfile(sys.argv[1]) # bekommt ein test.vec als Parameter
for vec in filter_list:
    testVec(vec)
vectorTest.py

Code: Alles auswählen

def testVec(vector):
    if not (isinstance(vector, filter.vector)):
        raise TypeError, "arg should be of type filter.vector"
Problem Nr1.
Ohne die Beschreibung von filter.vector auszulagern in ein importierbares Modul kann ich es in vectorTest.py gar nicht testen/bekannt machen.
Problem Nr2.
Außerdem wird der Test jedes mal getriggert, denn interessanterweise ist in testVec type(vector) ein __main__.vector. Wieso geht hier das filter.* verloren? Selbst wenn ich die Beschreibung auslagere, kann ich nicht gegen __main_.vector testen, sondern gegen filter.*

Habe durch forumsuche inzwischen herausgefunden, daß execfile, import *. from mod import *, unterschiedliche Namensräume aufmachen. Wie kann ich also den anderen Module filter.vector mitgeben/beschreiben, ohne ein erneutes import oder execfile?

Wäre für Hinweise sehr dankbar.

Nikolaus
BlackJack

Das sieht alles ein wenig konfus aus. "Innere" Klassen sind in Python zum Beispiel sehr ungewöhnlich. Was Du da mit den Klassen anstellst sieht auch ein wenig verwirrend aus. Kann man das nicht "flacher" gestalten?

Und `filter` ist der Name einer eingebauten Funktion. Das erkennt man auch am Syntaxhighlighting im Forum. Wenn `vectorTest.py` wirklich nur das enthält was Du gepostet hast, dann benutzt Du bei `isinstance()` das Attribut `vector` von eben dieser `filter()`-Funktion. Und das gibt's nicht.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wie BlackJack schon geschrieben hat. Eine Klasse in eine Klasse verpacken... Ich wußte garnicht das sowas überhaupt geht ;) Mir ist auch nicht klar, warum sowas gut sein soll...
Wenn man mehrere Klassen in das XYZ hat, sind diese auch bei import XYZ im Namensraum der Datei gekapselt...

Code: Alles auswählen

# XYZ.py
class vector(object):
    def __init__(self, newdata):
        self.a = filter.a(newdata)

Code: Alles auswählen

import XYZ
filter_list = [ XYZ.vector(...), XYZ.vector(...), .... ] 

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
nfilus

BlackJack hat geschrieben:Das sieht alles ein wenig konfus aus. "Innere" Klassen sind in Python zum Beispiel sehr ungewöhnlich. Was Du da mit den Klassen anstellst sieht auch ein wenig verwirrend aus. Kann man das nicht "flacher" gestalten?
Inner classes sind aber in anderen OOP durchaus gängig - in Java benutze ich sie sehr gerne für interne Strukturen. Ziel dieser Schachtelung ist es vor allem, daß es in Zukunft noch andere arten von Vektoren geben soll, die anders Aussehen.
BlackJack hat geschrieben: Und `filter` ist der Name einer eingebauten Funktion. Das erkennt man auch am Syntaxhighlighting im Forum. Wenn `vectorTest.py` wirklich nur das enthält was Du gepostet hast, dann benutzt Du bei `isinstance()` das Attribut `vector` von eben dieser `filter()`-Funktion. Und das gibt's nicht.
Hmm, das wäre durchaus möglich. Das Hilighting ist mir auch schon aufgefallen, allerdings habe ich gedacht, daß wäre nur eine Annahme des Editors und von Python entsprechend meiner Definition behandelt.

Trotzdem bleibt die Frage, wie execfile die Namensräume behandelt - import XYZ, wie Jens geschrieben hat, kann ich nicht benutzen, oder?!

Nikolaus
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

nfilus hat geschrieben:import XYZ, wie Jens geschrieben hat, kann ich nicht benutzen, oder?!
Ich kenn dein Programm nicht, aber warum sollte es nicht gehen???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

nfilus hat geschrieben:
BlackJack hat geschrieben:Das sieht alles ein wenig konfus aus. "Innere" Klassen sind in Python zum Beispiel sehr ungewöhnlich. Was Du da mit den Klassen anstellst sieht auch ein wenig verwirrend aus. Kann man das nicht "flacher" gestalten?
Inner classes sind aber in anderen OOP durchaus gängig - in Java benutze ich sie sehr gerne für interne Strukturen.
Python ist nicht Java. Interne Klassen in Java dienen meistens dem "gewaltsamen" verstecken von Klassen. In Python würde ich dem Klassennamen einfach einen Unterstrich voranstellen, damit sagt man Finger weg, das ist nicht für Aussenstehende. Solche Namen von Klassen und Funktionen werden aus dem Modul dann auch nicht "exportiert" wenn man irgendwo ein `from modulname import *` macht. Wobei man diesen `*` import sowieso nicht machen sollte.

Es sieht aber auch nicht nach dem aus, was Du beschreibst. Dir geht es offenbar um die Klasse `vector`, die steckt aber als "interna" in der `filter` Klasse, die nichts weiter ist als ein Namensraum.

Die Konvention Klassennamen mit einem Grossbuchstaben zu beginnen, gibt's übrigens auch in Python.
Ziel dieser Schachtelung ist es vor allem, daß es in Zukunft noch andere arten von Vektoren geben soll, die anders Aussehen.
Das erreicht man doch aber dadurch, dass man einfach andere Vektoren implementiert. Und nicht durch Schachtelung!?
Trotzdem bleibt die Frage, wie execfile die Namensräume behandelt - import XYZ, wie Jens geschrieben hat, kann ich nicht benutzen, oder?!
Wenn XYZ ein bekannter Name ist, den Du in den Quelltext schreiben kannst, dann sollte der Import klappen. Wenn XYZ der Name einer Zeichenkette ist, die den Modulnamen enthält, dann schau Dir mal die eingebaute Funktion `__import__()` an.
nfilus

BlackJack hat geschrieben:
Trotzdem bleibt die Frage, wie execfile die Namensräume behandelt - import XYZ, wie Jens geschrieben hat, kann ich nicht benutzen, oder?!
Wenn XYZ ein bekannter Name ist, den Du in den Quelltext schreiben kannst, dann sollte der Import klappen. Wenn XYZ der Name einer Zeichenkette ist, die den Modulnamen enthält, dann schau Dir mal die eingebaute Funktion `__import__()` an.
Das habe ich mir schon mal angeschaut gehabt. Das Problem war, daß die Module auf auf .vec enden und der importer akzeptiert diese Erweiterung nicht.
Ich habe in den python sourcen knee.py und importer.py gefunden - dort wird allerdings ein gesammtes Modul implementiert. Kann man nicht einfacher die suffixes ändern? Ich habe nur ein imp.get_suffixes() gefunden ...


Nikolaus
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Warum nennst du Python Module auch .vec :shock:
Es sind Python-Module, also sollten sie auch mit .py enden! Du könntest sie vielleicht auch XYZ.vec.py nennen, wenn du unbedingt das .vec drinn haben willst ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten