2014-03-05 21 views
1

好的,所以我有一個文件與控制器的網站的各種網頁。讓我們說下面的結構。Python合格進口全包

/controllers 
    /login_controller.py 
    /main_controller.py 
    /and_so_forth 

我知道,你可以動態地使用這個在__init__.py剪斷加載該文件夾所有控制器定義的符號:

__all__ = [] 

import pkgutil 
import inspect 

for loader, name, is_pkg in pkgutil.walk_packages(__path__): 
    module = loader.find_module(name).load_module(name) 

    for name, value in inspect.getmembers(module): 
     if name.startswith('__'): 
      continue 

     globals()[name] = value 
     __all__.append(name) 

的事情是,我喜歡有資格進口。所以說每個控制器文件都有一個控制器功能定義。有沒有什麼辦法與__init__.py魔法來實現的行爲,這樣,當我做的:

import controllers 

我可以調用的功能

controllers.controller_function_name() 

代替:

controllers.module_name.controller_function_name() 

?除去中間人。從本質上講,它的行爲就好像它只是一個模塊。

有沒有辦法做到這一點?

+0

無論你想要什麼,你都需要在'__init __。py'中導入。如果你想改變名稱(例如,使'main.py'中的'controller()'變成'main_controller'),你必須自己處理這個映射。 – BrenBarn

+0

@BrenBarn對不起,編輯了這個問題,使它更清晰。我不想改變名字;我只是想動態地導入一個包的所有模塊,而不會失去名稱限定。 – Aristides

+0

你的編輯仍然留下一些不清楚的事情。現在,當你執行'controllers.controller()'時,你期望調用哪個控制器? 'login_controler'中的一個或'main_controller'中的一個? – BrenBarn

回答

1

如果我理解你是正確的,你的代碼已經可以讓你做你想做的事情。

當你做globals()[name] = value時,你在__init__.py中創建一個全局變量。 __init__.py中的全局變量決定了軟件包名稱空間下可用的內容。因此,如果在代碼中創建了__init__.py中的變量some_controller,那麼您將可以執行controllers.some_controller

__all__隻影響當您使用from module import *時導入的內容。通過修改__all__,您正在影響如果您執行from controllers import *會發生的情況,但是如果您只是執行import controllers,則不會影響controllers下可用的內容。

+0

但我可以去除的是__all __。append(name)'部分,而不改變結果是什麼,對嗎? – Aristides

+1

@Aristides:基本上是,'__all__'隻影響'from foo import *'形式。看到我編輯的答案。 – BrenBarn