我想在Python中編寫一些(在我看來)可讀代碼。我需要一個包含許多類的模塊。從理論上講,我知道完成這一任務所需的一切:我可以簡單地將類定義放入單個模塊文件中。命名空間和類
爲了便於閱讀,我想將每個類定義放入單獨的文件中(它們開始很長!),並將所有這些類放入一個目錄中。無論何時我創建新文件,雖然它的內容在需要它們的地方都可見,但是裏面的類定義是用不需要的模塊來限定的。
我應該怎麼做?什麼是'Python'的方式來做到這一點?
我想在Python中編寫一些(在我看來)可讀代碼。我需要一個包含許多類的模塊。從理論上講,我知道完成這一任務所需的一切:我可以簡單地將類定義放入單個模塊文件中。命名空間和類
爲了便於閱讀,我想將每個類定義放入單獨的文件中(它們開始很長!),並將所有這些類放入一個目錄中。無論何時我創建新文件,雖然它的內容在需要它們的地方都可見,但是裏面的類定義是用不需要的模塊來限定的。
我應該怎麼做?什麼是'Python'的方式來做到這一點?
將它們全部導入__init__.py
之內,然後讓消費者導入包裝。
from .module1 import Class1
from .module2 import Class2
...
如果你想避免硬編碼在很多地方完整路徑,文件,類和函數名,你可以這樣做動態導入(幾乎)以下所有的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'>
這太棒了。適用於python 3.4.1。 – blockloop 2014-09-08 20:41:37
是什麼前面的點是什麼意思? – samuil 2011-02-25 12:33:13
@samuil:http://www.python.org/dev/peps/pep-0328/ – 2011-02-25 12:34:14
不幸的是,我僅限於Python 2.4,因爲腳本將在第三方嵌入式設備上運行。這個點符號在舊版本中似乎不起作用。我用這些子模塊的完整路徑替換了它。 – samuil 2011-02-25 13:14:26