zoukankan      html  css  js  c++  java
  • 模块与包

    模块

    一个模块就是一个包含了一组功能的python文件,比如spam.py,模块名为spam,可以通过import spam使用。

    模块的4种存在方式

    1.使用c编写并链接到python解释器的内置模块

    2.使用python编写的。py文件

    3.包:一堆py文件集合体

    q4.已被编译为共享库或dll的c或c++扩展

    导入模块

    1.编译执行模块所对应的py文件,形成对应的pyc文件

    2.产生该模块自家的全局名称空间

    3.在使用该模块的全局名称空间中产生一个名字(导入的模块名)

    以spam.py为例来介绍模块的使用:文件名spam.py,模块名spam

    #spam.py
    print('from the spam.py')
    
    money=1000
    
    def read1():
        print('spam模块:',money)
    
    def read2():
        print('spam模块')
        read1()
    
    def change():
        global money
        money=0
    

     import

    通过import关键字导入模块名

    “import”是引入一个完整的模块,“from…import”是引入模块中的一个或多个指定部分;

    “import”引入模块后,如果需要使用模块里的函数方法,则需要加上模块的限定名字,“from...import”则不用加模块的限定名字,直接使用其函数方法;

    import module

    编译执行模块所对应的py文件,形成对应的pyc文件

    产生该模块自己的全局名称空间

    在使用该模块的全局名称空间中产生一个名字(导入的模块名)

    优点:

    1.从文件级别组织代码,是同特性的功能能统一管理

    2.可以使用系统或第三方模块(拿来主义),来提高开发效率

     被导入模块有独立的名称空间

    每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突

    #test.py
    import spam 
    money=10
    print(spam.money)
    
    '''
    执行结果:
    from the spam.py
    1000
    '''
    

    为模块名起别名

    为已经导入的模块起别名的方式对编写可扩展的代码很有用

    1 import spam as sm
    2 print(sm.money)
    

    模块之from ... import...

    from模块名 import*

    导入的是模块中的_all_这个列表

    1.系统默认该列表不会收录开头的名字

    2.可以自定义_all_列表来规定外界通过*可以导入的名字

    from 模块名 import 名字1,名字2,。。。,名字n

    可以指名道姓导入模版中所有想导入的名字

    测试一:导入的函数read1,执行时仍然回到spam.py中寻找全局变量money
    #test.py
    from spam import read1
    money=1000
    read1()
    '''
    执行结果:
    from the spam.py
    spam->read1->money 1000
    '''
    
    #测试二:导入的函数read2,执行时需要调用read1(),仍然回到spam.py中找read1()
    #test.py
    from spam import read2
    def read1():
        print('==========')
    read2()
    
    '''
    执行结果:
    from the spam.py
    spam->read2 calling read
    spam->read1->money 1000

     py文件区分两种用途:模块与脚本

    编写好的一个python文件可以有两种用途:
        一:脚本,一个文件就是整个程序,用来被执行
        二:模块,文件中存放着一堆功能,用来被导入使用
    python为我们内置了全局变量__name__,
        当文件被当做脚本执行时:__name__ 等于'__main__'
        当文件被当做模块导入时:__name__等于模块名
    
    #作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
        if __name__ == '__main__':
    复制代码
    

    logging 模块

    logging模块是python提供的用于记录日志的模块

     日志级别

    在开始记录日志前还需要明确,日志的级别

    随着时间的推移,日志记录会非常多,成千上万行,如何快速找到需要的日志记录这就成了问题

    解决的方案就是 给日志划分级别

    logging模块将日志分为了五个级别,从高到低分别是:

    1.info 常规信息

    2.debug 调试信息

    3.warning 警告信息

    4.error 错误信息

    5.crtical 严重错误

    本质上他们使用数字来表示级别的,从高到低分别是10,20,30,40,50

    模块搜索路径

    模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块

    模块的查找顺序
    1、在第一次导入某个模块时(比如spam),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用
        ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看
    2、如果没有,解释器则会查找同名的内建模块
    3、如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。



    包是一种通过使用‘.模块名’来组织python模块名称空间的方式。
    包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来
    
    
    包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来
    随着功能越写越多,我们无法将所以功能都放到一个文件中,于是我们使用模块去组织功能,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性
    #文件内容
    
    #policy.py
    def get():
        print('from policy.py')
    
    #versions.py
    def create_resource(conf):
        print('from version.py: ',conf)
    
    #manage.py
    def main():
        print('from manage.py')
    
    #models.py
    def register_models(engine):
        print('from models.py: ',engine)
    

     包的使用 import

    1 import glance.db.models
    2 glance.db.models.register_models('mysql') 
    

    包的使用之from ... import ...

    需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

    1 from glance.db import models
    2 models.register_models('mysql')
    3 
    4 from glance.db.models import register_models
    5 register_models('mysql')
    

    from glance.api import *

    在讲模块时,我们已经讨论过了从一个模块内导入所有*,此处我们研究从一个包导入所有*。

     #在__init__.py中定义
    2 x=10
    3 
    4 def func():
    5     print('from api.__init.py')
    6 
    7 __all__=['x','func','policy']
    

    绝对导入和相对导入

    我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

    绝对导入:以glance作为起始

    相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

    例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

     在glance/api/version.py
    2 
    3 #绝对导入
    4 from glance.cmd import manage
    5 manage.main()
    6 
    7 #相对导入
    8 from ..cmd import manage
    9 manage.main()
    
    绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入
            优点: 执行文件与被导入的模块中都可以使用
            缺点: 所有导入都是以sys.path为起始点,导入麻烦
    
     相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入
            符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹
            优点: 导入更加简单
            缺点: 只能在导入包中的模块时才能使用

    
    
  • 相关阅读:
    浅谈流形学习
    流形(Manifold)初步【转】
    MATLAB中的函数的归总
    LBP特征提取实现
    Nginx 安装
    Linux执行.sh文件,提示No such file or directory的问题
    Ubuntu 安装后的配置及美化(二)
    Ubuntu 安装后的配置及美化(一)
    关于windows上 web 和 ftp 站点的创建及使用
    win10 + Lubuntu 双系统安装
  • 原文地址:https://www.cnblogs.com/legend27/p/11023223.html
Copyright © 2011-2022 走看看