2011-02-25 144 views
7

我想在Python中編寫一些(在我看來)可讀代碼。我需要一個包含許多類的模塊。從理論上講,我知道完成這一任務所需的一切:我可以簡單地將類定義放入單個模塊文件中。命名空間和類

爲了便於閱讀,我想將每個類定義放入單獨的文件中(它們開始很長!),並將所有這些類放入一個目錄中。無論何時我創建新文件,雖然它的內容在需要它們的地方都可見,但是裏面的類定義是用不需要的模塊來限定的。

我應該怎麼做?什麼是'Python'的方式來做到這一點?

回答

8

將它們全部導入__init__.py之內,然後讓消費者導入包裝。

from .module1 import Class1 
from .module2 import Class2 
... 
+0

是什麼前面的點是什麼意思? – samuil 2011-02-25 12:33:13

+0

@samuil:http://www.python.org/dev/peps/pep-0328/ – 2011-02-25 12:34:14

+0

不幸的是,我僅限於Python 2.4,因爲腳本將在第三方嵌入式設備上運行。這個點符號在舊版本中似乎不起作用。我用這些子模塊的完整路徑替換了它。 – samuil 2011-02-25 13:14:26

3

如果你想避免硬編碼在很多地方完整路徑,文件,類和函數名,你可以這樣做動態導入(幾乎)以下所有的Python文件發現在包中的子目錄。

,關鍵是要記住的是,__init__.py文件在很大程度上是一個不受約束的Python腳本本身,因此可以自由地執行它自己的相當複雜的處理,以確定哪些是在包的命名空間。

文件package\__init__.py

def _import_package_files(): 
    """ Dynamically import all the Python modules in this module's sub directory. """ 
    import os 
    import sys 
    import traceback 

    package_path = os.path.split(__file__)[0] 
    package_directory = os.path.split(package_path)[1] 

    for fn in os.listdir(package_directory): 
     globals_, locals_ = globals(), locals() 
     # process all python files in directory that don't start with underscore 
     if fn[0] != '_' and fn.split('.')[-1] in ('py', 'pyw'): 
      modulename = fn.split('.')[0] # filename without extension 
      subpackage = ".".join([package_directory, modulename]) 
      try: 
       module = __import__(subpackage, globals_, locals_, [modulename]) 
      except: 
       traceback.print_exc(file=sys.stdout) 
       raise # reraise exception 

_import_package_files() 

文件package\Class1.py

class Class1(object): 
    pass 

文件package\Class2.py

class Class2(object): 
    pass 

文件package\Class3.py

class Class3(object): 
    pass 

文件usepackage.py:從運行usepackage.py

import package 

print(package.Class1) 
print(package.Class2) 
print(package.Class3) 

輸出:

<module 'package.Class1' from 'C:\Files\package\Class1.pyc'> 
<module 'package.Class2' from 'C:\Files\package\Class2.pyc'> 
<module 'package.Class3' from 'C:\Files\package\Class3.pyc'> 
+0

這太棒了。適用於python 3.4.1。 – blockloop 2014-09-08 20:41:37