Python 包、模块、类以及代码文件和目录的一种管理方案

378 查看

1.要解决的问题

Python在语义中存在着模块(当然还有函数)这几个概念。

在编写Python代码时,我们需要管理代码的文件目录结构

这时候会遇到这样一种情况:

1.由于Python一个文件一个模块一个带__init__.py的目录算一个

2.而为了控制代码文件不要过大,我们需要的是一个类(几个类或加些许函数)分配一个文件

3.这时候会出现类似这样的语句:

以上除了直观上可以看出import过长外,隐藏的另一点是我们是希望一个类一个文件,在使用多个相关类的时候就必须写很多import。(注:我们可不想一堆代码扎堆,弄出一个超大代码文件。)

2.解决方案要达到的效果

由于Python里一个带__init__.py的目录算一个包,所以利用这一机制,把类文件放在包里,用包来管理类。

注:在Python里“包是模块,而模块不是包”。用system.modules可以取到的名字是包和模块都有的,而用__package__却能很好的区分包和模块。也就是“包其实是一种特殊的模块”。

3.解决方案

这就是解决方案的文件base.py,代码很短:

代码用意我写在注释里了,就是以装饰器来把类添加到包的__dict__和__all__里。__all__需要利用packet在包里生成,不这么做只会使得from package_name import * 后不能找到类,需要写具体的类名from package_name import ClassA。

4.使用解决方案

先来看下使用解决方案后的目录结构:

代码处就需要做到以下几点:

1.关于被导出的类文件里应该怎么做,这里以class_b.py为例子:

2.使用了导出功能的包要做什么,这里以package_a包为例:

5.总结

使用该解决方案可以归纳为两点:

1.用@base.export标记要导出的类或函数

2.在包__init__.py里初始化__all__ = base.packet(__name__)

3.(说好的只有两点呢?)其实第2点是可选的,不过最好加上。而在包的__init__.py里导入子模块才是真正的第2点。不然子模块不会被载入,也谈不上导出了。

最后,demo.py里可以这么写,和预期的效果一样:)