2011-02-25 108 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