2009-09-05 39 views
72

Tôi muốn xác định một hằng số sẽ có sẵn trong tất cả các mô-đun con của gói. Tôi đã nghĩ rằng nơi tốt nhất sẽ ở trong tập tin __init__.py của gói gốc. Nhưng tôi không biết làm thế nào để làm điều này. Giả sử tôi có một vài gói phụ và mỗi gói có một vài mô-đun. Làm thế nào tôi có thể truy cập biến đó từ các mô-đun này?Tôi có thể sử dụng __init__.py để xác định các biến toàn cầu không?

Tất nhiên, nếu điều này là hoàn toàn sai, và có một lựa chọn tốt hơn, tôi muốn biết điều đó.

Trả lời

120

Bạn sẽ có thể đặt chúng trong __init__.py. Điều này được thực hiện tất cả các thời gian.

mypackage/__init__.py:

MY_CONSTANT = 42 

mypackage/mymodule.py:

from mypackage import MY_CONSTANT 
print "my constant is", MY_CONSTANT 

Sau đó, nhập khẩu mymodule:

>>> from mypackage import mymodule 
my constant is 42 

Tuy nhiên, nếu bạn không có liên tục s, nó sẽ là hợp lý (thực hành tốt nhất, có lẽ) để đặt chúng trong một mô-đun riêng biệt (constants.py, config.py, ...) và sau đó nếu bạn muốn chúng trong không gian tên gói, hãy nhập chúng.

mypackage/__init__.py:

from mypackage.constants import * 

Tuy nhiên, điều này không tự động bao gồm các hằng số trong các không gian tên của module gói. Mỗi mô-đun trong gói sẽ vẫn phải nhập các hằng số một cách rõ ràng hoặc từ mypackage hoặc từ mypackage.constants.

+0

Vâng, có nghĩa là bạn phải nhập chúng. –

+9

Điều này đáng lẽ phải là câu trả lời được chấp nhận. Nếu bạn đang làm việc với Python 2.5 hoặc cao hơn, bạn cũng có thể sử dụng một phép nhập tương đối rõ ràng cũng như được mô tả [ở đây] (http://docs.python.org/2/tutorial/modules.html#intra-package-references): 'từ. nhập MY_CONSTANT' – ThatAintWorking

+0

Câu trả lời này đúng và đưa ra giải pháp trực tiếp thay vì giải pháp thay thế. Cảm ơn bạn đã cung cấp điều này và nó phải là câu trả lời được chấp nhận. +1 – Hazok

30

Bạn không thể làm điều đó. Bạn sẽ phải nhập khẩu một cách rõ ràng các hằng số của bạn vào mỗi không gian tên của từng mô-đun riêng biệt. Cách tốt nhất để đạt được điều này là để xác định các hằng số của bạn trong một "cấu hình" mô-đun và nhập nó ở khắp mọi nơi bạn cần nó:

# mypackage/config.py 
MY_CONST = 17 

# mypackage/main.py 
from mypackage.config import * 
+0

Yeah, một tập tin cấu hình là gì Tôi muốn. Tôi chỉ nghĩ rằng __init__.py sẽ là một nơi tốt. Giải pháp của bạn có vẻ như thực hành tiêu chuẩn. Là nó? –

+0

Điểm tốt. Tôi đã không nhận ra câu hỏi là có các hằng số _automatically_ được đặt trong không gian tên của tất cả các mô-đun gói. –

+0

Nhưng mỗi khi một tập lệnh nhập khẩu config.py, mã bên trong được thực thi. Bạn nên làm gì nếu mã bên trong config.py chỉ được chạy một lần? Giả sử tôi đang đọc tệp settings.json bên trong config.py và tôi không muốn mở() nó mỗi khi tôi nhập config.py. – Augiwan

2

Bạn có thể xác định biến toàn cầu từ bất kỳ đâu, nhưng đó thực sự là một ý tưởng tồi. nhập mô-đun __builtin__ và sửa đổi hoặc thêm thuộc tính vào mô-đun này và đột nhiên bạn có các hằng số hoặc hàm dựng sẵn mới. Trong thực tế, khi ứng dụng của tôi cài đặt gettext, tôi nhận hàm _() trong tất cả các mô-đun của mình, mà không cần nhập bất cứ thứ gì. Vì vậy, điều này là có thể, nhưng tất nhiên chỉ dành cho các dự án kiểu ứng dụng, không phải cho các gói hoặc mô-đun có thể sử dụng lại được.

Và tôi đoán không ai muốn giới thiệu phương pháp này. Có gì sai với một không gian tên? Ứng dụng đã nói có mô-đun phiên bản, do đó tôi có các biến "chung" sẵn có như version.VERSION, version.PACKAGE_NAME v.v.

1

Chỉ muốn thêm các hằng số đó có thể được sử dụng bằng tệp config.ini và được phân tích cú pháp trong tập lệnh bằng cách sử dụng thư viện configparser . Bằng cách này bạn có thể có hằng số cho nhiều trường hợp. Ví dụ: nếu bạn có hằng số tham số cho hai yêu cầu url riêng biệt chỉ cần gắn nhãn cho chúng như vậy:

mymodule/config.ini 
[request0] 
conn = '[email protected]' 
pass = 'admin' 
... 

[request1] 
conn = '[email protected]' 
pass = 'dinosaur' 
... 

Tôi tìm thấy tài liệu trên trang web Python rất hữu ích.Tôi không chắc chắn nếu có bất kỳ sự khác biệt giữa Python 2 và 3 vì vậy đây là các liên kết đến cả hai:

Đối với Python 3: https://docs.python.org/3/library/configparser.html#module-configparser

Đối với Python 2: https://docs.python.org/2/library/configparser.html#module-configparser

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