美文网首页
Python包、模块、类和代码文件目录的管理方案

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

作者: 蝴蝶兰玫瑰 | 来源:发表于2017-06-27 17:10 被阅读0次

    1.要解决的问题

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

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

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

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

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

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

    #第一种

    importpackage_a.class_a_fileascaf

    a=caf.ClassA()

    #第二种

    formpackage_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添加进去

    ifnotpackage.__name__in_packet_:

    _packet_[package.__name__]=[]

    _packet_[package.__name__].append(item.__name__)

    #原封不动地把item返回

    returnitem

    #它是个函数,在包__init__.py里用于获取__all__

    def packet(name):

    ifnotnamein_packet_:

    _packet_[name]=[]

    return_packet_[name]

    代码用意我写在注释里了,就是以装饰器来把类添加到包的__dict__和__all__里。__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

    importbase

    #2.使用export装饰器,装饰要导出的类或函数

    @base.export

    classClassB:pass

    #2.同样的export可以导出函数

    @base.export

    def func_b():

    print('func_b')

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

    # ./package_a/__init__.py

    #1.导入base

    importbase

    #2.导入将要导出的子模块,需要具体模块名字的形式,from . import * 不可用

    from.importclass_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()学好python你需要一个良好的环境,一个优质的开发交流群,群里都是那种相互帮助的人才是可以的,我有建立一个python学习交流群,在群里我们相互帮助,相互关心,相互分享内容,这样出问题帮助你的人就比较多,群号是304加上050最後799,这样就可以找到大神聚合的群,如果你只愿意别人帮助你,不愿意分享或者帮助别人,那就请不要加了,你把你会的告诉别人这是一种分享。无论是学习任何一门语言,基础知识,就是基础功非常的重要,找一个有丰富编程经验的老师或者师兄带着你会少走很多弯路, 你的进步速度也会快很多,无论我们学习的目的是什么,不得不说Python真的是一门值得你付出时间去学习的优秀编程

    语言。

    感觉写的好,对你有帮助,就点个赞呗,别光只收藏哈.~( ̄▽ ̄)~

    相关文章

      网友评论

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

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