2011-08-15 27 views
5

Tôi có một mô-đun được chia nhỏ hơn một nửa giữa các chức năng loại tiện ích và chức năng lõi api. Tôi cần phải có tất cả chúng trong __all__ để có help() hữu ích, và cũng để xác định cái nào trong số nhiều hàm/lớp/etc trong mô-đun để sử dụng bên ngoài, nhưng tôi cũng muốn hỗ trợ from mymodule import * như một cách để có được chỉ là chức năng cốt lõi vào các mô-đun khác. Có cách nào làm được việc này không?Làm thế nào để xác định một `từ ... import * 'api riêng biệt từ __all__ trong một mô-đun?

Trả lời

4

Hầu như. Trong khi bạn không thể có __all__ làm nhiệm vụ tăng gấp đôi theo cách này, bạn có thể thêm mô-đun của riêng ảo api mà sau đó có thể được nhập khẩu ...

class fake_module(object): 
    def __init__(self, name, *args): 
     self.name = name 
     self.__all__ = [] 
     all_objects = globals() 
     for name in args: 
      self.__dict__[name] = all_objects[name] 
      self.__all__.append(name) 
    def register(self): 
     sys.modules["%s.%s" % (__name__, self.name)] = self 

    fake_module('api', 'class1', 'class2', 'func3', 'exception4').register() 

Sau đó, trong các module khác thay vì from mymodule import * bạn có thể làm để from mymodule.api import * chỉ nhận được tập hợp con mong muốn trong khi vẫn giữ mọi thứ trong một mô-đun duy nhất.

Note: from ... import * không phải là thực hành thường tốt, và cần được sử dụng cẩn thận tuyệt vời và chỉ với modules/gói mà explicity nói rằng họ đã được thiết kế với việc sử dụng như vậy trong tâm trí.

+0

Không có nhu cầu thực sự để đi tất cả điên ở đây ... chỉ cần thực hiện một tập tin riêng biệt gọi là 'api' và nhập khẩu tập hợp con của các chức năng vào nó, và sau đó nhập khẩu nó vào __init__.py của mô-đun. – Dave

+0

@Dave: mô-đun là các tệp đơn lẻ và do đó không có '__init __. Py's. gói là những cái mà * phải * có tệp '__init __. py' và có thể có các tệp khác. Thư viện tôi đang phát triển phù hợp thoải mái vào một tập tin duy nhất (có, tôi đã thử các tuyến đường gói cho nó, và cuối cùng chuyển trở lại một tập tin duy nhất/mô-đun bố trí). –

+0

đủ công bằng. Khi bạn giả định ...:) – Dave

2

Tôi không nghĩ rằng có một cách để làm điều đó - ít nhất không phải là một cách sạch sẽ. Ngay cả các mô-đun chính thức Python có rất nhiều hàm util xuất hiện trong tài liệu của nó. Những gì tôi sẽ làm, nếu sự tách biệt là quan trọng, là tạo ra hai mô-đun khác nhau. Dù sao, để sử dụng from module import * không phải là một thực hành tốt và tôi sẽ không khuyên bạn nên làm điều đó, ít hơn nhiều để thiết kế mô-đun của bạn để phù hợp thực hành như vậy :)

+0

Đối với mô-đun tiện ích do người dùng xác định, đó là thực tế khá tốt. – Evpok

+0

@Evpok mô-đun tiện ích do người dùng xác định là gì? Các mô-đun có được sử dụng trong bảng điều khiển Python không? – brandizzi

+0

Tôi có nghĩa là một số mô-đun có phím tắt hoặc hằng số được sử dụng ở mọi nơi trong ứng dụng, giá trị mặc định, số ma thuật, dấu gạch ngang bẩn ... – Evpok

0

Bạn không thể có những gì bạn muốn: import * hành vi được xác định bởi __all__.

+0

Không chính xác những gì tôi muốn, nhưng khá darn gần. 'từ mymodule.api import *' là đủ tốt. –

4

Ethan, fake_module của bạn có khả năng được thực hiện tốt hơn với trăn cũ đơn giản. Chỉ cần di chuyển mã của bạn vào thiết lập thư mục:

mymodule 
    __init__.py 
    api.py 
    util.py 
    _mymodule.py 

Trường hợp _mymodule.py chứa mã hiện tại của bạn.

Trong bạn __init__.py:

from _mymodule import * 

Trong bạn api.py

# explicity import only those api classes you want to expose 
# this will allow you to call `from mymodule.api import *` 
import from _mymodule ApiClass1 
import from _mymodule ApiClass2 
# etc 

Làm tương tự cho bạn util.py

# explicity import only those util classes you want to expose 
# this will allow you to call `from mymodule.util import *` 
import from _mymodule UtilClass1 
import from _mymodule UtilClass2 
# etc 

Vì vậy, bây giờ bạn có thể:

# import everything willy nilly for your help() 
from mymodule import * 

# or import only the "public" values from api and util 
from mymodule.api import * 
from mymodule.util import * 

Tách mã của bạn như thế này có thể hữu ích cho việc tổ chức mô-đun lớn mà bạn vẫn muốn có thể truy cập từ một không gian tên cấp cao nhất. Nhưng tôi sẽ phải đồng ý với brandizzi rằng việc sử dụng from mymodule import * trong mã đang sử dụng mô-đun này thường là một ý tưởng tồi. Những gì bạn có được dễ dàng nhập khẩu bạn bị mất trong tính minh bạch của mã đang sử dụng những nhập khẩu đó.

+0

Triệt để hoàn thành câu trả lời chi tiết cách thực hiện thông thường. –

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