2009-12-04 20 views
12

Ví dụ, tôi muốn tạo một plugin giả kim thuật sql cho một dự án khác. Và tôi muốn đặt tên cho mô-đun đó là sqlalchemy.py. Vấn đề với điều này là nó ngăn tôi nhập sqlalchemy:Làm cách nào để ngăn mô-đun Python tự nhập?

#sqlalchemy.py 
import sqlalchemy 

Điều này sẽ làm cho mô-đun tự nhập. Tôi đã thử điều này, nhưng dường như không hoạt động:

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

Bất kỳ đề xuất nào?

+1

Điều thú vị, tôi nhận được kết quả ngược lại một thời gian ngắn trước khi thực hiện nhập từ {something {something} {something} ' – MitMaro

+0

Tôi không hoàn toàn rõ ràng về những gì bạn đang cố gắng làm. Liệu nó có phải là 'bóng' mô-đun 'sqlalchemy' thực sự với mô-đun của riêng bạn, để các mô-đun khác cố gắng nhập 'sqlalchemy' thay vào đó, nhưng (chỉ) bạn mới có thể nhận được' sqlalchemy' thực sự? –

+0

Không, đó là mô-đun con của gói lớn hơn. Nó chỉ xảy ra như vậy mà Python dường như chọn nhập khẩu tương đối trước khi nhập khẩu tuyệt đối. –

Trả lời

12

Sửa: như OP giờ đây đã nói rằng vấn đề này là một trong nhập khẩu tương đối được ưa thích đến tuyệt đối, giải pháp đơn giản cho vấn đề cụ thể của OP là thêm vào lúc bắt đầu của các mô-đun from __future__ import absolute_import làm thay đổi điều đó "sở thích "/ đặt hàng.

Sau đây vẫn áp dụng đối với các vấn đề tế nhị của hai đụng độ nhập khẩu tuyệt đối (mà không xuất hiện để được gì OP hiện đang phải đối mặt với ...):

Khi bạn đã nhập khẩu một module có tên x, mô-đun đó được ghi lại trong sys.modules['x'] - thay đổi sys.path khi bạn đang thực hiện sẽ không thay đổi sys.modules. Bạn cũng sẽ cần thay đổi trực tiếp sys.modules.

Ví dụ: xem xét:

$ 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 

(chạy lại sẽ sử dụng và hiển thị các tập tin pyc thay vì những cái py tất nhiên).

Không phải cách tiếp cận rõ ràng nhất, và dĩ nhiên, không thể truy cập từ mô-đun foo ban đầu nữa (vì mục nhập sys.modules của nó đã bị di dời), nhưng bạn có thể chơi các thủ thuật mong manh hơn nếu cần (stash sys.modules["foo"] một nơi nào đó trước khi xóa nó, sau khi bạn nhập khẩu khác foo đặt mô-đun đó ở một nơi khác và phục hồi bản gốc sys.modules["foo"] - vv, vv), tùy thuộc vào nhu cầu chính xác của bạn. (Tất nhiên, tránh các cuộc đụng độ tên ở nơi đầu tiên sẽ gần như luôn luôn đơn giản hơn waltzing tất cả xung quanh chúng theo cách này ;-).

+0

Thực ra, 'sys.modules ['sqlalchemy']' trỏ tới sqlalchemy thực sự. 'sys.modules ['storm.databases.sqlalchemy']' trỏ đến module của tôi. Nó chỉ xảy ra như vậy mà Python dường như chọn nhập khẩu tương đối trên nhập khẩu tuyệt đối. –

+1

@Jason, vâng, trừ khi bạn 'từ __future__ nhập khẩu absolute_import', là giải pháp đơn giản nhất khi vấn đề là một trong những nhập khẩu tương đối so với tuyệt đối (câu trả lời của tôi vẫn được khuyến nghị cho việc nhập khẩu tuyệt đối xung đột). Hãy để tôi chỉnh sửa câu trả lời cho phù hợp. –

+0

Xin lỗi, tôi nên rõ ràng hơn trong câu hỏi của tôi. :-) Phiên bản nào của Python là nhập '__future__' tương thích? –

3

Đừng đặt tên nó là sqlalchemy.py?

Nghiêm túc. Tôi nghĩ rằng đây là vấn đề nhập khẩu tuyệt đối có nghĩa vụ phải giải quyết. Trong python 2,5 nó không nên xảy ra, nhưng tôi có thể sai

+0

Tôi có thể làm điều đó, nhưng dự án tự động tải các plugin bằng tên mô-đun. Không thích hợp hơn, nhưng đó là một chút trong tay tôi. –

+0

Nó xảy ra theo Python 2.6.4. Tôi đã không thử nó trong các phiên bản khác. –

2

Bạn chỉ có thể bị đốt cháy bởi sự khác biệt giữa mã đang chạy trong trình thông dịch tương tác và từ một tệp. Loại bỏ các thử nghiệm cho sys.path[0] bị trống (khi chạy từ một tệp, nó không phải là) và nhập khẩu bây giờ sẽ làm việc như bạn muốn.

$ 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]) 
'' 

CHỈNH SỬA: áp dụng ở trên nếu mô-đun chính của bạn là sqlalchemy.py. Nếu mô đun của bạn được mô-đun khác nhập, bạn cũng sẽ phải thay đổi sys.modules như Alex giải thích.

Các vấn đề liên quan