美文网首页编程Python开发技术
Python 包、模块、类以及代码文件和目录的一种管理方案

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

作者: PyChina | 来源:发表于2016-10-13 22:52 被阅读424次

原文出处: 士止刀口

1.要解决的问题

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

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

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

1.由于Python一个文件算一个模块,一个带init.py的目录算一个包。

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

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

#第一种
import package_a.class_a_file as caf
a = caf.ClassA()
 
#第二种
form package_a.class_a_file import *
a = ClassA()
 
#另外几种就不意义列举了...

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

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

#文件目录结构
#|--demo.py
#|--package_a
#   |--__init__.py
#   |--class_a.py  #类ClassA
#   |--class_b.py  #类ClassB和函数func_b()
 
#demo.py中可以直接使用
from package_a import *
 
a = ClassA()
b = ClassB()
func_b()

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

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

3.解决方案

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

import sys
 
_packet_ = {}
 
#它是个装饰器,item是类,或者函数
def export(item):
    #获取item的模块对象
    module = sys.modules[item.__module__]
    #由模块对象得到包对象
    package = sys.modules[module.__package__]
    #把item添加到包的__dict__里
    package.__dict__[item.__name__] = item
    #生成所有使用该解决方案的包的__all__变量,并把导出的item添加进去
    if not package.__name__ in _packet_:
        _packet_[package.__name__] = []
    _packet_[package.__name__].append(item.__name__)
    #原封不动地把item返回
    return item
 
#它是个函数,在包__init__.py里用于获取__all__
def packet(name):
    if not name in _packet_:
        _packet_[name] = []
    return _packet_[name]

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

4.使用解决方案

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

#文件目录结构(使用后结构只多了base.py)
#|--base.py
#|--demo.py
#|--package_a
#   |--__init__.py
#   |--class_a.py  #类ClassA
#   |--class_b.py  #类ClassB和函数func_b()

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

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

# ./package_a/class_b.py
 
#1.需要导入base
import base
 
#2.使用export装饰器,装饰要导出的类或函数
@base.export
class ClassB:pass
 
#2.同样的export可以导出函数
@base.export
def func_b():
    print('func_b’)

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

# ./package_a/__init__.py
 
#1.导入base
import base
 
#2.导入将要导出的子模块,需要具体模块名字的形式,from . import * 不可用
from . import class_a,class_b
 
#3.用packet初始化__all__,这个可选,主要是看要不要支持 from 的用 * 导入
__all__ = base.packet(__name__)
 
#4.这个是可选的,因为如果用了__all__会影响from *。可以用export把__init__.py里的项,加入__all__
@base.export
def pafunc():
    print('pafunc')
5.总结

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

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

2.在包init.py里初始化all = base.packet(name)

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

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

# ./demo.py
 
from package_a import *
 
a = ClassA() # 上面的实例没有给出,不过假设有ClassA在class_a.py里的
b = ClassB()
func_b()

今年第六届大会PyConChina2016,由PyChina.org发起,CPyUG/TopGeek 等社区协办,将在2016年9月10日(上海)9月25日(深圳)10月15日(北京、杭州)地举办的针对Python开发者所举办的最盛大和权威的Python相关技术会议,由PyChina社区主办,致力于推动各类Python相关的技术在互联网、企业应用等领域的研发和应用。

您可以点击此处
了解更多详情,或者扫描下图二维码:

相关文章

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

    原文出处: 士止刀口 1.要解决的问题 Python在语义中存在着包、模块、类(当然还有函数)这几个概念。 在编写...

  • Python包、模块、类和代码文件目录的管理方案

    1.要解决的问题 Python在语义中存在着包、模块、类(当然还有函数)这几个概念。 在编写Python代码时,我...

  • Python高级

    包(lib)、模块(module) 模块:编写Python代码的py文件包:用来分门别类存放模块代码的文件夹,【一...

  • python 高级

    包和模块 模块: 模块就是一个保存了python代码的文件,模块能定义函数,类和变量。模块也能包含可执行的代码。...

  • 6.Python-模块和包

    模块和包 模块 Python会将所有 .py结尾的文件认定为Python代码文件,一个完整的python文件就是一...

  • PyQT实战学习(1)anaconda环境

    python的文件管理方式是模块和包,这些当然就需要管理了,如果选择在系统的python目录下,当然好办。但是,副...

  • 核心开发

    Python核心开发 一.包和模块 1. 包和模块的定义 为了更加有好的对python代码进行管理,出现了包和模块...

  • Python包及其引入方法

    一、Python包 模块所在目录看做是包,目录名即为包名。 二、Python包创建 创建过程举例(模块中不包含类)...

  • 6、Python的组织结构

    python的层级结构:包 -> 模块 -> 类 ->函数、变量 包:文件夹,模块:文件 命名空间:...

  • 【学习记录】Python3版本(5:模块)

    综述 为了防止函数重名以及便于修正管理,大型工程文件一般都会有“模块”。 python用目录来查看和组织模块,这种...

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/dskgyttx.html