2009-05-26 24 views
12

Mặc dù nó khá tầm thường trong Python để nhập mô-đun "con" vào mô-đun khác và liệt kê các thuộc tính của nó, nó trở nên khó khăn hơn khi bạn muốn nhập tất cả các mô-đun con.Làm thế nào để tìm tất cả các mô-đun con trong Python?

Tôi đang tạo thư viện công cụ cho ứng dụng 3D hiện có. Mỗi công cụ có mục menu và menu phụ riêng. Tôi muốn công cụ chịu trách nhiệm tạo các menu của riêng mình vì nhiều công cụ thay đổi dựa trên ngữ cảnh và các mẫu. Tôi muốn mô-đun cơ bản của tôi có thể tìm thấy tất cả các mô-đun con và kiểm tra chức năng create_menu() và gọi nó nếu nó tìm thấy nó.

Cách dễ nhất để khám phá tất cả các mô-đun con là gì?

+0

Điều này có liên quan không? [('pkg_resources' từ gói setuptools)] (http://jeetworks.org/node/49) –

+1

Sử dụng [pkgutil.walk_packages] (http://docs.python.org/library/pkgutil.html#pkgutil. walk_packages). Mô-đun – Dag

+1

không phải là gói –

Trả lời

0

sử dụng dir()imp module

+0

imp trông giống như mô-đun chính xác tôi cần! Cảm ơn. – Soviut

+11

Đó là một câu trả lời khá ngắn gọn, tôi không hiểu tại sao nó được chấp nhận. Tài liệu cho dir() giả định đối tượng của bạn đã có các thuộc tính. Bạn có thể xây dựng và nói * làm thế nào * một nên sử dụng dir() cho việc tìm kiếm các mô-đun chưa được nhập khẩu? – bignose

+3

Nope: '$ mkdir foo $ touch foo/__ init__.py $ touch foo/bar.py $ python Python 2.7.1+ (r271: 86.832, 11 Tháng Tư 2011, 18:05:24) [GCC 4.5.2] trên linux2 Nhập "trợ giúp", "bản quyền", "tín dụng" hoặc "giấy phép" để biết thêm thông tin. >>> nhập foo >>> foo >>> dir (foo) ['__builtins__', '__doc__', '__file__', '__name__ ',' __package__ ',' __path__ '] >>> từ thanh nhập foo >>> thanh ' –

1

Khi tôi còn là một loại và lập trình chỉ mới bắt đầu bằng Python Tôi đã viết này cho bot IRC mô-đun của tôi:


    # Load plugins 

    _plugins = [] 

    def ifName(name): 
     try: 
      return re.match('([^_.].+)\.[^.]+', a).group(1) 
     except: 
      return None 

    def isValidPlugin(obj): 
     from common.base import PluginBase 
     try: 
      if obj.__base__ == PluginBase: 
       return True 
      else: 
       return False 
     except: 
      return False 

    plugin_names = set(ifilter(lambda a: a!=None, [ifName(a) for a in os.listdir(os.path.join(os.getcwd(), 'plugins'))])) 
    for plugin_name in plugin_names: 
     try: 
      plugin = __import__('plugins.'+plugin_name, fromlist=['plugins']) 
      valid_plugins = filter(lambda a: isValidPlugin(a), [plugin.__getattribute__(a) for a in dir(plugin)]) 
      _plugins.extend(valid_plugins) 
     except Exception, e: 
      logger.exception('Error loading plugin %s', plugin_name) 

    # Run plugins 

    _plugins = [klass() for klass in _plugins] 

Nó không an toàn hay "đúng" cách, nhưng có lẽ nó sẽ hữu ích. Đó là rất mã cũ vì vậy xin đừng đánh tôi.

+0

Có, bạn nên sử dụng mô-đun imp như dfa đã đề cập. – deno

-1

Bạn có thể thử glob bing thư mục:

import os 
import glob 

modules = glob.glob(os.path.join('/some/path/to/modules', '*.py')) 

Sau đó, bạn có thể thử nhập họ:

checked_modules 
for module in modules: 
    try: 
     __import__(module, globals(), locals()) # returns module object 
    except ImportError: 
     pass 
    else: 
     checked_modules.append(module) 
3

Tôi nghĩ rằng cách tốt nhất để làm điều này loại plugin được sử dụng entry_pointsAPI for querying them.

+0

Đây phải là câu trả lời được chấp nhận. Đăng ký các mô-đun thông qua các điểm vào là cách tiếp cận rõ ràng hơn, có chủ ý và Pythonic khi bạn muốn khám phá chúng trong thời gian chạy và không có tác dụng phụ khiến tất cả chúng được nhập theo cách 'pkgutil.walk_packages' thực hiện . –

1

Giải pháp trên vượt qua hệ thống tệp để tìm mô-đun con là ok miễn là bạn triển khai mọi plugin làm mô-đun dựa trên hệ thống tệp.

Một cách linh hoạt hơn sẽ là danh sách plugin rõ ràng trong mô-đun chính của bạn và có mọi plugin (cho dù mô-đun được tạo bởi tệp, động hoặc thậm chí là một lớp) tự thêm vào danh sách đó một cách rõ ràng. Có thể thông qua chức năng registerPlugin.

Hãy nhớ rằng: "rõ ràng là tốt hơn là ẩn" là một phần của zen của python.

+0

để làm việc này, bạn phải có cách đảm bảo rằng các mô-đun plugin được nhập khi bạn khởi động ứng dụng của mình, nếu không chúng sẽ không có cơ hội đăng ký. nó là vấn đề về thịt gà và trứng. mà không đi qua/tự động nhập mô-đun, bạn sẽ nhập thủ công tất cả các mô-đun trong mô-đun chính của mình, phủ nhận sự cần thiết của chức năng đăng ký nhưng vi phạm nguyên tắc chính không cần biết về các plugin cụ thể – Anentropic

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