2009-08-11 9 views
6

genannt werden Lets sagen, dass ich in einer Datei bin openid.py genannt, und ich tue:Python: Wie kann ich, welches Modul zu importieren wählen, wenn sie die gleichen

from openid.consumer.discover import discover, DiscoveryFailure 

Ich habe das openid Modul auf meinem PYTHONPATH aber die Dolmetscher scheint zu versuchen, meine openid.py Datei zu verwenden. Wie kann ich die Bibliotheksversion erhalten?

(Natürlich wäre etwas anderes als die offensichtliche "Umbenennen Sie Ihre Datei" Antwort wäre nett).

+7

‚benennen Sie Ihre Datei‘ – SilentGhost

+0

Was ist der Grund für die Datei nicht umbenennen? Es scheint wie kleine Lösung im Vergleich zu suchen nach einem Weg um ihn herum. – Zoomulator

+0

Die Datei sollte semantisch openid heißen, da sie sich in einem Modul mit "Typen" von Aliasen befindet. openid ist der Name des Typs. –

Antwort

9

Das ist der Grund, warum absolute Importe als das neue Standardverhalten ausgewählt wurden. Sie sind jedoch noch nicht der Standardwert in 2.6 (vielleicht in 2.7 ...). Sie können ihr Verhalten jetzt erhalten, indem sie aus der Zukunft zu importieren:

from __future__ import absolute_import 

Sie können von Nick metnioned im PEP mehr darüber erfahren oder (leichter zu verstehen, glaube ich) in dem Dokument "What's New in Python 2.5".

3

Benennen Sie es um. Dies ist die Idee hinter Namensräumen. Ihr openid könnte ein Untermodul in Ihrem obersten Modul project sein. Ihr email wird mit Top-Modul email in Stdlib kollidieren.

Da Ihr Openid nicht universal ist, bietet es einen speziellen Fall für Ihr Projekt.

+4

Eigentlich glaube ich, dass die Idee hinter Namespaces * nicht * darin besteht, sie in etwas Einzigartiges umzubenennen;) myproject.openid ist etwas anderes als openid. Mit den neuen absoluten Importen erhält import openid immer das systemweite (z. B. stdlib) Modul und die relative .openid wird das openid Submodul im aktuellen Modul bekommen. – c089

+0

ist es natürlich nicht. ** Wenn ** er sein Modul 'project', sollte er' project.openid' verwenden. Es ist nicht klar, warum OP das tut, was er tut, aber wenn er kein Modul 'project' hat, sollte er' openid' in etwas anderes umbenennen. – SilentGhost

+0

korrekt. Außerhalb des Pakets ist es pkg.openid. Aber innerhalb der Datei "openid.py" kann ich nicht auf die Bibliothek "openid" zugreifen. Das ist das Hauptproblem. –

1

können Sie relative oder absolute Importe verwenden (abhängig von den Besonderheiten Ihrer Situation), die in PEP 328 zuletzt abgedeckt ist. Natürlich sollten Sie solche Namenskonflikte nicht erstellen und Ihre Datei umbenennen.

+0

Auch wenn der semantisch korrekte Name für die Datei openid ist? Wie wenn es in einem Verzeichnis von Arten von Aliasen zusammen mit, E-Mail, Webseite, Domain, etc? –

+0

@Paul: Sogar dann. Wenn es in einem "Verzeichnis von Alias-Typen" ist, dann sollte das wirklich ein Paket sein, und dann ist es pkg.openid, was eindeutig ist. –

+0

korrekt. Außerhalb des Pakets ist es pkg.openid. Aber innerhalb der Datei "openid.py" kann ich nicht auf die Bibliothek "openid" zugreifen. Das ist das Hauptproblem. –

-1

Sie könnten versuchen, sys.path shuffling, um die interessanten Verzeichnisse nach vorne zu bewegen, bevor Sie den Import durchführen.

+0

Wird nicht helfen, wenn 'sys.modules ['openid']' bereits gesetzt ist, wie es im OP der Fall wäre, da er in 'openid.py' ist. –

+0

@Alex Warum sollte das der Fall sein? Wird die aktuelle Datei automatisch zu sys.modules hinzugefügt? Eine schnelle test.py <"import sys; print sys.modules.keys()", wenn ausgeführt, schlägt ansonsten vor !? – ThomasH

+0

Ein Modul, das _imported_ ist, wird zu sys.modules unter seinem richtigen Namen hinzugefügt; Die eine Datei, die als "Hauptprogramm" ausgeführt wird, erhält stattdessen den konventionellen Namen "__main__". Aber wenn Sie dieses openid.py als Hauptmodul ausführen, gibt es keinen Grund, es auf sys.path zu installieren! –

2

Ich werde nicht in die Polemik auf Umbenennung erhalten und stattdessen konzentrieren Sie sich auf die zeigen, wie zu tun, was Sie wollen (ob es „gut für Sie“ ist oder nicht ;-). Die Lösung ist nicht schwierig ...

Nur __path__ einstellen! Eine kleine Demonstration:

$ mkdir /tmp/modules /tmp/packages 
$ mkdir /tmp/packages/openid 
$ echo 'print "Package!"' > /tmp/packages/openid/__init__.py 
$ gvim /tmp/modules/openid.py 
$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid' 
Module! 
Package! 

dies zeigt eine Modul openid ein gleichnamiges Paket sogar importieren Verwaltung obwohl der Weg des Moduls früher in sys.path kommt, undsys.modules['openid'] klar sind zu diesem Zeitpunkt bereits eingestellt. Und all das "Geheimnis" ist in einfachen Code des openid.py ...:

print "Module!" 
__path__ = ['/tmp/packages'] 
import openid 

ohne __path__ Zuordnung, natürlich, es nur Module! emittieren würde.

Funktioniert natürlich auch für den Import von Submodulen innerhalb des Pakets. Do:

$ echo 'print "Submod!"' > /tmp/packages/openid/submod.py 

und ändern openid.py der letzten Zeile zu

from openid import submod 

und Sie werden sehen:

$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid' 
Module! 
Package! 
Submod! 
$ 
+0

In Bezug auf sys.modules ['openid'] wird gesetzt. Du hast das auch in einem anderen Kommentar gesagt, aber ich bin mir nicht so sicher. Warum sollte das so sein? Wird die aktuelle Datei automatisch zu sys.modules hinzugefügt? Eine schnelle test.py <"import sys; print 'test' in sys.modules.keys()", wenn ausgeführt, schlägt anders vor !? – ThomasH

+0

Als ich auf den anderen Kommentar geantwortet habe: Die eine Datei, die als Hauptmodul ausgeführt wird, geht stattdessen in 'sys.modules ['__ main __']' (da ihr '__name__' künstlich und konventionell auf' __main__' gesetzt ist). Deshalb importiere ich hier Openid, um zu zeigen, dass "__path__" immer noch funktioniert. Wenn alles, was Sie brauchen, mit openid.py ist, es als main auszuführen, dann gibt es keinen Grund, es in sys.path zu haben. –

+0

Ich dachte, dass das Problem des OP einfach von der Tatsache herrührt, dass "." kommt früher in sys.path, also wird das aktuelle Verzeichnis nach 'openid' durchsucht, wo das importierende Skript openid.py gefunden wird. Aber wenn Sie die 'interessanten' Verzeichnisse von sys.path nach vorne verschieben, wird die andere 'openid' (das Modul) zuerst gefunden, und alles ist in Ordnung. – ThomasH

Verwandte Themen