2012-01-30 141 views
2

我正在使用Django,我喜歡將我的模型,視圖和測試分離到子目錄中。在Python中實現「from。import *」的最佳方式是什麼?

但是,這意味着我需要在導入該目錄中每個模塊的每個子目錄中保留一個__init__.py

我寧願只是把一些呼叫,說:

from some_library import import_everything 
import_everything() 

這將對作爲遍歷當前目錄相同的效果,並在該目錄中導入所有的.py文件。

什麼是最好/最簡單的方法來實現這個?

這裏是什麼我的Django應用程序目錄(基本)的樣子:

some_django_app/ 
    models/ 
     __init__.py 
     create.py 
     read.py 
     update.py 
     delete.py 
    views/ 
     __init__.py 
     create.py 
     read.py 
     update.py 
     delete.py 
    forms/ 
     __init__.py 
     create.py 
     update.py 
    tests/ 
     __init__.py 
     create.py 
     read.py 
     update.py 
     delete.py 

所以,你可以看到,做一個「適當」的Django應用程序,我所有的初始化 .py文件需進口每個目錄中的所有其他.py文件。我寧願在那裏有一些簡單的樣板。

+0

您可以添加示例目錄佈局嗎? – Cameron 2012-01-30 18:49:39

+0

更新爲包含目錄佈局。 – slacy 2012-01-30 19:01:56

+0

請注意'來自。 import *'通常是一個壞主意,因爲名字空間可能會在您不知情的情況下被覆蓋。請參閱[有關該主題的文檔](http://docs.python.org/howto/doanddont.html#from-module-import) – 2012-01-30 19:42:31

回答

1

使用synthesizerpatel's answer給出的信息,你可以實現import_everything這樣:

import os 
import sys 

def import_everything(path): 
    # Insert near the beginning so path will be the item removed with sys.path.remove(path) below 
    # (The case when sys.path[0] == path works fine too). 
    # Do not insert at index 0 since sys.path[0] may have a special meaning 
    sys.path.insert(1,path) 
    for filename in os.listdir(path): 
     if filename.endswith('.py'): 
      modname = filename.replace('.py', '') 
      module = __import__(modname, fromlist = [True]) 
      attrs = getattr(module, '__all__', 
          (attr for attr in dir(module) if not attr.startswith('_'))) 
      for attr in attrs: 
       # print('Adding {a}'.format(a = attr)) 
       globals()[attr] = getattr(module, attr) 
    sys.path.remove(path) 

,並且可以使用這樣的:

print(globals().keys()) 
# ['import_everything', '__builtins__', '__file__', '__package__', 'sys', '__name__', 'os', '__doc__'] 

import_everything(os.path.expanduser('~/test')) 

print(globals().keys()) 
# ['hashlib', 'pythonrc', 'import_everything', '__builtins__', 'get_input', '__file__', '__package__', 'sys', 'mp', 'time', 'home', '__name__', 'main', 'os', '__doc__', 'user'] 
4

在您app/models/__init__.py加上這些行:

from app.models.create import * 
    from app.models.read import * 
    from app.models.update import * 
    from app.models.delete import * 

這將是您最好的選擇簡潔和可讀性。 from app.models import *現在將加載其他每個文件中的所有類/ etc。同樣,from app.models import foo將加載foo,無論它定義在哪個文件中。

+0

是的,這正是我現在所做的,我覺得它很累。對於每個新的測試用例或表單,我都需要不斷更新__init__.py。對於大多數情況(模型,視圖),這是可以的,但是對於測試來說這是最糟糕的,因爲我喜歡在那裏有很多文件,而不是一個巨大的tests.py,__init__.py在其中有很多行。 – slacy 2012-01-30 20:10:27

+0

@slacy這聽起來像是一種糟糕的組織方式。爲什麼不把測試分成邏輯分組 - model_tests.py,view_tests.py等等? (或其他一些對該應用有意義的分組,例如user_tests,guest_tests或其他) – Izkata 2012-01-30 21:04:34

+0

是的,實際上,我們確實有model_tests.py和view_tests,但即使是那些文件也會得到> 1000行,我們最終將它們分開。 :) – slacy 2012-01-30 22:28:55

相關問題