2009-12-04 12 views
12

Na przykład chcę utworzyć wtyczkę alchemiczną sql dla innego projektu. I chcę nazwać ten moduł sqlalchemy.py. Problem z tym jest to, że pozwala mi importowania sqlalchemy:Jak mogę zapobiec importowaniu samego modułu Pythona?

#sqlalchemy.py 
import sqlalchemy 

To sprawi, że sam import modułu. Próbowałem już, ale to nie działa:

import sys 
#Remove the current directory from the front of sys.path 
if not sys.path[0]: 
    sys.path.pop(0) 
import sqlalchemy 

Jakieś sugestie?

+1

Zabawna rzecz, przed chwilą otrzymałem wynik odwrotny, gdy robiłem "z {czegoś} importu {coś}" – MitMaro

+0

Nie jestem całkowicie pewien, co próbujesz zrobić. Czy to "cienie" prawdziwego modułu 'sqlalchemy' z własnego, aby inne moduły próbujące zaimportować' sqlalchemy' otrzymały twoje, ale (tylko) twoje mogą uzyskać prawdziwe 'sqlalchemy'? –

+0

Nie, to moduł częściowy większego pakietu. Tak się składa, że ​​wydaje się, że Python wybiera względny import przed bezwzględnym importem. –

Odpowiedz

12

Edit: jak OP teraz wspomnieć, że problem jest jednym z względną importu jest korzystna do absolutu, najprostszym rozwiązaniem konkretnego problemu OP jest dodanie na początku modułu from __future__ import absolute_import co zmienia, że ​​„pierwszeństwo "/ Zamawianie.

Poniższa nadal ma zastosowanie do łaskotki wydaniu dwóch zderzających importu bezwzględne (co nie wydaje się być to, co PO stoi obecnie w obliczu ...):

Po zaimportowaniu modułu o nazwie x, ten moduł jest zapisany w sys.modules['x'] - zmiana sys.path, jak to robisz, nie zmieni sys.modules. Będziesz także musiał bezpośrednio zmienić sys.modules.

przykład rozważyć:

$ cat a/foo.py 
print __file__; import sys; sys.path.insert(0, "b"); del sys.modules["foo"]; import foo 
$ cat b/foo.py 
print __file__ 
$ python2.5 -c'import sys; sys.path.insert(0, "a"); import foo' 
a/foo.py 
b/foo.py 

(uruchomione ponownie użyje i pokazać pliki .pyc zamiast na .py te oczywiście).

Nie najczystsze podejście, i oczywiście w ten sposób oryginalny moduł foo jest nieuchronnie niedostępny z zewnątrz (ponieważ jego wpis sys.modules został przemieszczony), ale w razie potrzeby można zagrać kolejne kruche sztuczki (ukryj sys.modules["foo"] gdzieś przed skasowaniem, po zaimportowaniu innego foo umieść ten moduł gdzieś indziej i przywróć oryginalny sys.modules["foo"] - itd., itp.), w zależności od Twoich konkretnych potrzeb. (Oczywiście, unikanie zderzeń nazw w pierwszej kolejności prawie zawsze byłoby prostsze niż walcowanie wokół nich w ten sposób ;-).

+0

Właściwie 'sys.modules ['sqlalchemy']' wskazuje na prawdziwą sqlalchemy. 'sys.modules ['storm.databases.sqlalchemy']' wskazuje na mój moduł. Tak się składa, że ​​wydaje się, że Python wybiera względny import w stosunku do bezwzględnego importu. –

+1

@Jason, tak, chyba że 'od __future__ import absolute_import', które jest najprostszym rozwiązaniem, gdy problem jest względny w stosunku do bezwzględnego importu (moja odpowiedź jest nadal zalecana w przypadku importów bezwzględnych będących w konflikcie). Pozwól mi odpowiednio edytować odpowiedź. –

+0

Przepraszam, powinienem być bardziej przejrzysty w moim pytaniu. :-) Z jakiej wersji Python jest zgodny import? __future__'? –

3

Nie nazwij go sqlalchemy.py?

Poważnie. Myślę, że jest to problem, który ma rozwiązać bezwzględny import. W pythonie 2.5 to nie powinno się zdarzyć, ale mogę się mylić

+0

Mogę to zrobić, ale projekt dynamicznie ładuje wtyczki według nazwy modułu. Nie jest to korzystne, ale jest to nieco poza zasięgiem moich rąk. –

+0

Zdarza się to w Pythonie 2.6.4. Nie próbowałem go w innych wersjach. –

2

Być może po prostu zaczynasz się palić różnicami między uruchomionym kodem w interaktywnym interprerze i plikiem. Usuń test dla sys.path[0], który jest pusty (gdy uruchamiany z pliku, nie jest) i import powinien teraz działać tak, jak chcesz.

$ more sqlalchemy.py 
import sys 
print sys.path[0] 
sys.path.pop(0) 
import sqlalchemy 
print sqlalchemy.__file__ 
$ python sqlalchemy.py 
/Users/nad 
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sqlalchemy/__init__.pyc 
$ python 
Python 2.6.4 (r264:75706, Oct 28 2009, 20:34:51) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys; print repr(sys.path[0]) 
'' 

EDIT: dotyczy jeśli główny moduł jest sqlalchemy.py. Jeśli twój moduł zostanie zaimportowany przez inny moduł, będziesz także musiał zmienić sys.modules, jak wyjaśnia Alex.

Powiązane problemy