2009-08-11 13 views
6

phép nói rằng tôi đang ở trong một tập tin gọi là openid.py và tôi làm:Python: Làm thế nào tôi có thể chọn mô-đun để nhập khẩu khi họ được đặt tên giống nhau

from openid.consumer.discover import discover, DiscoveryFailure 

Tôi có module openid trên PYTHONPATH của tôi nhưng thông dịch viên dường như đang cố gắng sử dụng tệp openid.py của tôi. Làm thế nào tôi có thể nhận được phiên bản thư viện?

(Tất nhiên, điều gì đó khác với câu trả lời rõ ràng 'đổi tên tệp của bạn' sẽ tốt đẹp).

+7

'đổi tên tập tin của bạn' – SilentGhost

+0

lý do không đổi tên tập tin là gì? Nó có vẻ như sửa chữa nhỏ so với được tìm kiếm một cách xung quanh nó. – Zoomulator

+0

Tệp tin ngữ nghĩa nên được gọi là openid, vì nó nằm trong một mô-đun có "loại" bí danh. openid là tên của loại. –

Trả lời

9

Đó là lý do lý do nhập khẩu tuyệt đối đã được chọn làm hành vi mặc định mới. Tuy nhiên, chúng không phải là mặc định trong 2.6 (có thể là 2,7 ...). Bạn có thể nhận được hành vi của họ bây giờ bằng cách nhập chúng từ tương lai:

from __future__ import absolute_import 

Bạn có thể tìm hiểu thêm về vấn đề này trong PEP metnioned Nick hoặc (dễ hiểu hơn, tôi nghĩ) trong tài liệu "What's New in Python 2.5".

3

Đổi tên thành. Đây là ý tưởng đằng sau không gian tên. openid của bạn có thể là mô-đun phụ trong mô-đun hàng đầu project. email của bạn sẽ xung đột với mô-đun hàng đầu email trong stdlib.

vì openid của bạn không phổ biến, nó cung cấp trường hợp đặc biệt cho dự án của bạn.

+4

Thực ra, tôi nghĩ ý tưởng đằng sau các không gian tên là * không * phải đổi tên nó thành một cái gì đó độc đáo;) myproject.openid là một thứ khác với openid. Với nhập khẩu tuyệt đối mới, nhập openid sẽ luôn nhận được mô-đun toàn hệ thống (ví dụ: stdlib) và tương đối .openid sẽ nhận mô đun con openid trong mô-đun hiện tại. – c089

+0

tất nhiên là không. ** Nếu ** anh ta mô-đun của mình 'dự án' hơn anh ta nên sử dụng' project.openid'. Không rõ tại sao OP lại làm những gì anh ta đang làm, nhưng nếu anh ta không có module 'project', thì anh ta nên đổi tên 'openid' thành cái gì đó khác. – SilentGhost

+0

chính xác. bên ngoài gói nó là pkg.openid. Nhưng bên trong tập tin "openid.py", tôi không thể truy cập thư viện "openid". Đó là vấn đề chính. –

1

Bạn có thể sử dụng nhập tương đối hoặc tuyệt đối (tùy thuộc vào chi tiết cụ thể về trường hợp của bạn), được bao gồm trong PEP 328 gần đây nhất. Tất nhiên, nghiêm túc, bạn không nên tạo ra xung đột đặt tên như thế này và nên đổi tên tập tin của bạn.

+0

Ngay cả khi tên đúng ngữ nghĩa cho tệp là openid? Giống như nếu nó nằm trong một thư mục các loại bí danh cùng với, email, trang web, tên miền, v.v ...? –

+0

@Paul: Ngay cả lúc đó. Nếu nó nằm trong một "thư mục của các loại bí danh", thì đó thực sự phải là một gói, và sau đó nó là pkg.openid, mà là rõ ràng. –

+0

chính xác. bên ngoài gói nó là pkg.openid. Nhưng bên trong tập tin "openid.py", tôi không thể truy cập thư viện "openid". Đó là vấn đề chính. –

-1

Bạn có thể thử xáo trộn sys.path, để di chuyển các thư mục thú vị về mặt trước trước khi thực hiện nhập.

+0

Sẽ không giúp đỡ nếu 'sys.modules ['openid']' đã được thiết lập, vì nó sẽ nằm trong trường hợp của OP như trong 'openid.py'. –

+0

@Alex Tại sao điều đó lại xảy ra? Tệp hiện tại có tự động được thêm vào sys.modules không? Một test.py <"import sys; print sys.modules.keys()", khi chạy, gợi ý khác đi !? – ThomasH

+0

Một mô-đun _imported_ được thêm vào sys.modules dưới tên thật của nó; một tệp được chạy dưới dạng "chương trình chính" thay vào đó là tên thông thường của '__main__'. Nhưng nếu bạn đang chạy openid.py đó làm module chính thì không có lý do gì để có nó trên sys.path ngay từ đầu! –

2

Tôi sẽ không tham gia vào các chiến dịch đổi tên và thay vào đó tập trung vào việc chỉ cho bạn cách làm những gì bạn muốn (cho dù đó là "tốt cho bạn" hay không ;-). Giải pháp không khó ...

Chỉ cần đặt __path__! Một cuộc biểu tình nhỏ:

$ 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! 

này cho thấy một mô-đun openid quản lý để nhập khẩu một đồng âm gói mặc dù con đường của mô-đun đến trước đó trong sys.path, sys.modules['openid'] rõ ràng là đã được thiết lập tại thời điểm đó. Và tất cả những "bí mật" là mã đơn giản openid.py của ...:

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

mà không có sự phân công __path__, tất nhiên, nó sẽ chỉ phát ra Module!.

Cũng hoạt động để nhập các mô-đun con trong gói, tất nhiên. Do:

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

và thay đổi openid.Dòng cuối cùng py để

from openid import submod 

và bạn sẽ thấy:

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

Về sys.modules ['openid'] đang được thiết lập. Bạn cũng nói điều này trong một bình luận khác, nhưng tôi không chắc lắm. Tại sao điều đó lại xảy ra? Tệp hiện tại có tự động được thêm vào sys.modules không? Một test.py nhanh chóng <"import sys; print 'test' trong sys.modules.keys()", khi chạy, gợi ý khác đi !? – ThomasH

+0

Như tôi đã trả lời cho bình luận khác: một tập tin đang chạy khi module chính đi vào 'sys.modules ['__ main __']' thay vì ('__name__' của nó là giả tạo và thông thường được đặt thành' __main__'). Đó là lý do tại sao tôi ** nhập ** vào openid ở đây, để cho thấy rằng '__path__' vẫn hoạt động. Nếu tất cả những gì bạn cần w/openid.py là chạy nó như là chính thì không có lý do gì để có nó trong sys.path. –

+0

Tôi nghĩ rằng vấn đề của OP bắt nguồn từ thực tế là '.' đến sớm hơn trong sys.path, do đó thư mục hiện tại được tìm kiếm cho 'openid', nơi tìm thấy tập lệnh openid.py nhập khẩu. Nhưng nếu bạn chuyển các thư mục 'thú vị' của sys.path sang mặt trước của nó, thì 'openid' khác (module) được tìm thấy trước, và mọi thứ đều ổn. – ThomasH

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