Re: [Python-de] Globaler "prefix" o.ae.

Dinu Gherman wrote:
Daher würde ich zumindest es gerne sehen, wenn diese Geschichte an einem anderen Ort (vielleicht auf einer Debian-Liste?) ausge- tragen würde,
Du liest hier noch nicht lange mit, oder?
und, sofern eine Lösung existiert, diese dann hier bekannt gemacht würde.
Soifz. [psf 10.1] Eine mögliche Lösung habe ich doch schon erklärt. Für diejenigen, denen das jetzt immer noch nicht klar ist: *Wenn* man den Originalquelltext von Python-Paketen nicht ändern kann oder will, aber *trotzdem* Namenskollisionen mit bestehenden Paketen vermeiden will, muss man eben ein neues Python-Paket schnüren, in das man die vorhandenen Python-Pakete einpackt (hier: mypackage). Dann *muss* man den Suchpfad geeignet anpassen. Eine Ansatzpunkt dafür ist die PYTHONPATH-Umgebungsvariable (diese kann bei der Debian- Paketinstallation auch *systemweit* automatisch angepasst werden), ein anderer ist sys.path (welches den PYTHONPATH sowie Default-Pfade beinhaltet). Das sieht z. B. folgendermassen aus: -[mypackage/__init__.py]---------------------------------------------- import sys import os def _init(): my_path = os.path.dirname(__file__) if not my_path in sys.path: sys.path.insert(1, my_path) _init() del _init -[mypackage/database/ps2/Database/database.py]------------------------ from common.config.Profile import profiles def foo(): profiles.bar() -[mypackage/common/config/Profile/profiles.py]------------------------ def bar(): print 42 -[test.py]------------------------------------------------------------ import mypackage from mypackage.database.ps2.Database import database as mydatabase #from otherpackage.database import database mydatabase.foo() #database.bla() ---------------------------------------------------------------------- Wie man sieht, kann der Originalquelltext hier unverändert bleiben; nur die __init__.py des äusseren Python-Pakets muss man hinzufügen, und dann muss man das äussere Python-Paket explizit importieren (da dieses dann den Suchpfad um seinen Verzeichnispfad ergänzt). Das äussere Paket muss sich natürlich selbst im Suchpfad befinden. Diese Lösung ist natürlich nicht besonders schön; besser wäre sauberer Quelltext im Originalpaket. Aber es funktioniert – $ PYTHONPATH=../tmp python test.py 42 –, und der Änderungs- und Dokumentationsaufwand ist minimal. Vermutlich gibt es auch noch bessere Hacks, die Regeln für das Finden des Moduls bei der import-Anweisung sind ja recht komplex (RTFM). In jedem Fall wurde bereits von anderer Seite korrekt darauf hingewiesen, dass ein Python-Paket mit unsauberer Struktur allenfalls im privaten Debian- Repository aufgenommen werden wird. HTH -- PointedEars Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Sag mal, hast Du echt spitze Ohren, oder ist das nur ein 'Spitzname'? Das würde mich jetzt echt interessieren. Gruß, Bernhard -----Original Message----- From: Thomas 'PointedEars' Lahn <PointedEars@web.de> Sender: python-de-bounces+bernhard.bockelbrink=gmx.de@python.org Date: Mon, 12 Sep 2011 21:55:33 To: <python-de@python.org> Reply-To: Thomas 'PointedEars' Lahn <usenet@PointedEars.de>, Die Deutsche Python Mailingliste <python-de@python.org> Subject: Re: [Python-de] Globaler "prefix" o.ae. Dinu Gherman wrote:
Daher würde ich zumindest es gerne sehen, wenn diese Geschichte an einem anderen Ort (vielleicht auf einer Debian-Liste?) ausge- tragen würde,
Du liest hier noch nicht lange mit, oder?
und, sofern eine Lösung existiert, diese dann hier bekannt gemacht würde.
Soifz. [psf 10.1] Eine mögliche Lösung habe ich doch schon erklärt. Für diejenigen, denen das jetzt immer noch nicht klar ist: *Wenn* man den Originalquelltext von Python-Paketen nicht ändern kann oder will, aber *trotzdem* Namenskollisionen mit bestehenden Paketen vermeiden will, muss man eben ein neues Python-Paket schnüren, in das man die vorhandenen Python-Pakete einpackt (hier: mypackage). Dann *muss* man den Suchpfad geeignet anpassen. Eine Ansatzpunkt dafür ist die PYTHONPATH-Umgebungsvariable (diese kann bei der Debian- Paketinstallation auch *systemweit* automatisch angepasst werden), ein anderer ist sys.path (welches den PYTHONPATH sowie Default-Pfade beinhaltet). Das sieht z. B. folgendermassen aus: -[mypackage/__init__.py]---------------------------------------------- import sys import os def _init(): my_path = os.path.dirname(__file__) if not my_path in sys.path: sys.path.insert(1, my_path) _init() del _init -[mypackage/database/ps2/Database/database.py]------------------------ from common.config.Profile import profiles def foo(): profiles.bar() -[mypackage/common/config/Profile/profiles.py]------------------------ def bar(): print 42 -[test.py]------------------------------------------------------------ import mypackage from mypackage.database.ps2.Database import database as mydatabase #from otherpackage.database import database mydatabase.foo() #database.bla() ---------------------------------------------------------------------- Wie man sieht, kann der Originalquelltext hier unverändert bleiben; nur die __init__.py des äusseren Python-Pakets muss man hinzufügen, und dann muss man das äussere Python-Paket explizit importieren (da dieses dann den Suchpfad um seinen Verzeichnispfad ergänzt). Das äussere Paket muss sich natürlich selbst im Suchpfad befinden. Diese Lösung ist natürlich nicht besonders schön; besser wäre sauberer Quelltext im Originalpaket. Aber es funktioniert – $ PYTHONPATH=../tmp python test.py 42 –, und der Änderungs- und Dokumentationsaufwand ist minimal. Vermutlich gibt es auch noch bessere Hacks, die Regeln für das Finden des Moduls bei der import-Anweisung sind ja recht komplex (RTFM). In jedem Fall wurde bereits von anderer Seite korrekt darauf hingewiesen, dass ein Python-Paket mit unsauberer Struktur allenfalls im privaten Debian- Repository aufgenommen werden wird. HTH -- PointedEars Please do not Cc: me. / Bitte keine Kopien per E-Mail. _______________________________________________ python-de maillist - python-de@python.org http://mail.python.org/mailman/listinfo/python-de

Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
Eine mögliche Lösung habe ich doch schon erklärt. Für diejenigen, denen das jetzt immer noch nicht klar ist: [...]
Du könntest Dein unangebracht arrogantes Gehabe durchaus lassen.
-[mypackage/__init__.py]---------------------------------------------- [...] my_path = os.path.dirname(__file__) if not my_path in sys.path: sys.path.insert(1, my_path)
Das funktioniert nicht, wie schon an anderer Stelle im Thread diskutiert. Bau doch mal Dein Paket und ein identisches unter "otherpackage" (d.h., otherpackage.__init__.py ist identisch zu mypackage.__init__.py). Dann: mypackage/common/Base.py, otherpackage/common/Base.py (identisch) --------------------8<------------- class Base(object): def __str__(self): return __file__ --------------------8<------------- mypackage/database/Databse.py, otherpackage/database/Databse.py (identisch) --------------------8<------------- from common.Base import Base class Database(Base): pass --------------------8<------------- test.py: --------------------8<------------- from mypkg.database.Database import Database from otherpkg.database.Database import Database as Otherbase ob = Otherbase() db = Database() print ob, db --------------------8<------------- zeigt, dass otherpkg.database.Database die falsche Baseklasse nimmt.
Diese Lösung ist natürlich nicht besonders schön; besser wäre sauberer Quelltext im Originalpaket. Aber es funktioniert –
$ PYTHONPATH=../tmp python test.py 42
nicht. ~/poo$ python test.py /home/ole/poo/mypkg/common/Base.py /home/ole/poo/mypkg/common/Base.py
HTH
Score adjusted?

Ole Streicher wrote:
Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
-[mypackage/__init__.py]---------------------------------------------- [...] my_path = os.path.dirname(__file__) if not my_path in sys.path: sys.path.insert(1, my_path)
Das funktioniert nicht,
Das funktioniert hier sehr gut.
wie schon an anderer Stelle im Thread diskutiert.
Wo genau?
Bau doch mal Dein Paket und ein identisches unter "otherpackage" (d.h., otherpackage.__init__.py ist identisch zu mypackage.__init__.py).
Dann: mypackage/common/Base.py, otherpackage/common/Base.py (identisch) --------------------8<------------- class Base(object): def __str__(self): return __file__ --------------------8<-------------
mypackage/database/Databse.py, otherpackage/database/Databse.py (identisch) --------------------8<------------- from common.Base import Base class Database(Base): pass --------------------8<-------------
test.py: --------------------8<------------- from mypkg.database.Database import Database from otherpkg.database.Database import Database as Otherbase
ob = Otherbase() db = Database() print ob, db --------------------8<-------------
zeigt, dass otherpkg.database.Database die falsche Baseklasse nimmt.
Du hast mypkg hier gar nicht importiert, daher wird auch der code in mypkg/__init__.py nicht ausgeführt und sys.path nicht geändert.
Diese Lösung ist natürlich nicht besonders schön; besser wäre sauberer Quelltext im Originalpaket. Aber es funktioniert –
$ PYTHONPATH=../tmp python test.py 42
nicht.
~/poo$ python test.py /home/ole/poo/mypkg/common/Base.py /home/ole/poo/mypkg/common/Base.py
Dein Beispiel hat mit meinem nicht allzuviel zu tun. Logisch, dass das *so* nicht funktioniert. -- PointedEars Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
Ole Streicher wrote:
Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
-[mypackage/__init__.py]---------------------------------------------- Das funktioniert nicht, Das funktioniert hier sehr gut. wie schon an anderer Stelle im Thread diskutiert. Wo genau?
Message-ID: <87ipozgtsa.fsf@news.ole.ath.cx> und folgende. Sowas kommt halt von "Score adjusted".
zeigt, dass otherpkg.database.Database die falsche Baseklasse nimmt.
Du hast mypkg hier gar nicht importiert, daher wird auch der code in mypkg/__init__.py nicht ausgeführt und sys.path nicht geändert.
Nicht? test.py: --------------------8<------------- import sys from mypkg.database.Database import Database from otherpkg.database.Database import Database as Otherbase ob = Otherbase() db = Database() print ob, db print sys.path --------------------8<------------- $ python test.py /home/ole/poo/mypkg/common/Base.pyc /home/ole/poo/mypkg/common/Base.pyc ['/home/ole/poo', '/home/ole/poo/otherpkg', '/home/ole/poo/mypkg'] Wer schreibt dann wohl den dritten Eintrag? Du kannst natürlich auch vor das "from mypkg..." noch ein "import mypkg" setzen -- das ändert am Ergebnis nichts.
Dein Beispiel hat mit meinem nicht allzuviel zu tun. Logisch, dass das *so* nicht funktioniert.
Es ist Dein Beispiel -- ich habe mir lediglich erlaubt, "otherpackage" etwas zu konkretisieren. Das zeigt aber eben, dass diese Lösung (Pfad anpassen) das Problem nur kaschiert und nicht löst: die packages heißen immer noch common und database, und können lediglich zusätzlich unter mypackage.common bzw. mypackage.database angesprochen werden. Nie Namensraumverschmutzung und das Konfliktpotential bleibt bestehen, und das war doch der Anlass für mein erstes Posting: | Sowas lässt sich natürlich nicht so ohne weiteres z.B. in ein | Python-Repository einpflegen, weil es mit jedem anderen Paket, welches | so frech ist, "common" und "database" zu verwenden, clashen würde.

Ole Streicher wrote:
Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
Ole Streicher wrote:
Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
-[mypackage/__init__.py]---------------------------------------------- Das funktioniert nicht, Das funktioniert hier sehr gut. wie schon an anderer Stelle im Thread diskutiert. Wo genau?
Message-ID: <87ipozgtsa.fsf@news.ole.ath.cx> und folgende. Sowas kommt halt von "Score adjusted".
Ich denke nicht, dass ich mir Deine Unverschämtheiten noch länger gefallen lassen muss.
zeigt, dass otherpkg.database.Database die falsche Baseklasse nimmt.
Du hast mypkg hier gar nicht importiert, daher wird auch der code in mypkg/__init__.py nicht ausgeführt und sys.path nicht geändert.
Nicht?
Nein, *hattest* Du nicht.
test.py: --------------------8<------------- import sys from mypkg.database.Database import Database from otherpkg.database.Database import Database as Otherbase
ob = Otherbase() db = Database() print ob, db print sys.path --------------------8<-------------
$ python test.py /home/ole/poo/mypkg/common/Base.pyc /home/ole/poo/mypkg/common/Base.pyc ['/home/ole/poo', '/home/ole/poo/otherpkg', '/home/ole/poo/mypkg']
Wer schreibt dann wohl den dritten Eintrag? Du kannst natürlich auch vor das "from mypkg..." noch ein "import mypkg" setzen -- das ändert am Ergebnis nichts.
Es ändert am Ergebnis schon etwas, nur *anscheinend* nichts Relevantes.
Dein Beispiel hat mit meinem nicht allzuviel zu tun. Logisch, dass das *so* nicht funktioniert.
Es ist Dein Beispiel --
Nein, war es nicht. Ich habe allerdings inzwischen die Lust verloren, mich weiter mit dem Problem zu beschäftigen. Denn es ist nicht mein Problem, und derjenige, der das Problem hat, steuert selbst nichts Konstruktives zur Lösung bei. -- PointedEars Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:
wie schon an anderer Stelle im Thread diskutiert. Wo genau? Message-ID: <87ipozgtsa.fsf@news.ole.ath.cx> und folgende. Sowas kommt halt von "Score adjusted". Ich denke nicht, dass ich mir Deine Unverschämtheiten noch länger gefallen lassen muss.
Musst Du nicht. Es ist nur halt nicht besonders sinnvoll, wenn man in einem Thread, von dem man Teile ignoriert, mitdiskutieren möchte. Man läuft halt Gefahr, Diskussionsteile zu verpassen.
Du hast mypkg hier gar nicht importiert, daher wird auch der code in mypkg/__init__.py nicht ausgeführt ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ und sys.path nicht geändert. ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Nicht? Nein, *hattest* Du nicht.
mypkg/__init__.py wird m.E. auch bei from mypkg.database.Database import Database ausgeführt. Diese Zeile hatte ich bei mir drin, und wie man am Ergebnis sieht, wird auch sys.path entsprechend erweitert. Was Du mit dem obigen Satz meinst, ist mir daher unklar.
Wer schreibt dann wohl den dritten Eintrag? Du kannst natürlich auch vor das "from mypkg..." noch ein "import mypkg" setzen -- das ändert am Ergebnis nichts. Es ändert am Ergebnis schon etwas, nur *anscheinend* nichts Relevantes.
Eben. Unabhängig ob es drin ist, wird das falsche Base-Package importiert. Warum ist das import jetzt für das Problem wichtig, dass Du es hier erwähnst?
Dein Beispiel hat mit meinem nicht allzuviel zu tun. Logisch, dass das *so* nicht funktioniert. Es ist Dein Beispiel -- Nein, war es nicht.
OK, ich habe die urprüngliche Klassenhierarchie verwendet (database.Database.Database ist abgeleitet common.Base.Base). Der Mechanismus __init__.py ist allerdings identisch zu Deinem. Und ich habe eine Implementation für otherpackage zugefügt. Welche dieser Änderungen bewirkt denn, dass es nicht funktioniert? Oder soll ich es nochmal mit Deinem Code wiederholen?
Ich habe allerdings inzwischen die Lust verloren, mich weiter mit dem Problem zu beschäftigen. Denn es ist nicht mein Problem, und derjenige, der das Problem hat, steuert selbst nichts Konstruktives zur Lösung bei.
Moment: ich habe Deinen Vorschlag implementiert und gestestet, genauso wie alle anderen hier genannten. Und ich habe eine Reihe konstruktiver Vorschläge gemacht, von sys.path.insert(0,...) bis hin zur Anfrage, ob module-Finder bzw. Loader hier helfen könnten. Wenn ich das Problem selbst lösen könnte, würde ich hier nicht fragen. Was erwartest Du also?

Am 13.09.2011 17:29, schrieb Thomas 'PointedEars' Lahn:
--------------------8<------------- from mypkg.database.Database import Database from otherpkg.database.Database import Database as Otherbase
ob = Otherbase() db = Database() print ob, db --------------------8<-------------
zeigt, dass otherpkg.database.Database die falsche Baseklasse nimmt. Du hast mypkg hier gar nicht importiert, daher wird auch der code in
Fachlich falsch. `from mypkg.database.Database import` implizierte den Import von mypkg. -- Schönen Gruß - Regards Hartmut Goebel Dipl.-Informatiker (univ.), CISSP, CSSLP Goebel Consult Spezialist für IT-Sicherheit in komplexen Umgebungen http://www.goebel-consult.de Monatliche Kolumne: http://www.cissp-gefluester.de/ Goebel Consult ist Mitglied bei http://www.7-it.de
participants (4)
-
bernhard.bockelbrink@gmx.de
-
Hartmut Goebel
-
Ole Streicher
-
Thomas 'PointedEars' Lahn