zoukankan      html  css  js  c++  java
  • 21、,模块与包的使用

    一、Python文件的使用途径

    1.1、一个Python文件的两种用途

      1.被当成文件使用

      2.被当成模块使用

    1.2、两种使用途径的区别

      1.2.1、导入模块之后,模块里面的名字和和使用Python文件是一样的,区别在于模块的里面的名字只作用于模块本身,存储在模块设定的名称空间中

      无论是查看还是修改操作都是模块本身,不影响调用位置。而当文件使用的时候是使用全局的变量。  

      1.2.2、每个py文件都内置了__name__变量,该变量在py文件被当做脚本执行时赋值为“__main__”,在py文件被当做模块导入时赋值为模块名

      作为模块foo.py的开发者,可以在文件末尾基于__name__在不同应用场景下值的不同来控制文件执行不同的逻辑

    if __name__ == '__main__':
        foo.py被当做脚本执行时运行的代码
    else:
        foo.py被当做模块导入时运行的代码

    二、模块的导入

    2.1、模块导入的要求

      import导入模块的时候要求加前缀"模块."

      优点:不会和当前名称空间内的名字冲突

      缺点:加前缀比较麻烦

    2.2、在模块导入时发生的事      form 。。。 import。。。

      1.产生一个模块的名称空间

      2.运行模块,将产生的名字放入名称空间中

      3.将模块的名称空间里面的名字添加到文件所在的名称空间中

    2.3、模块二次导入

      当模块被再次导入的时候,由于第一次导入的名称空间已经在内存中,所以不会再运行模块文件的程序代码,而是从内存中绑定引用

    2.4、import。。。和form。。。importde。。。的区别

      import。。。导入的是模块内的所有名字

      form。。。importde。。。导入的是模块内,某个名字

    三、模块搜索的优先级

      优先顺序:内存===》内置模块===》sys。path

      sys。path的值为列表,存放着各种文件夹的路径,当内存和内置模块中没有时,将会通过sys。path去硬盘中按照顺序寻找。

            其中第一个文件是当前执行文件的所在文件夹

      sys。modules 的值为字典,存放的是内存中已经有的模块,key对应的是模块名,value对应的是绝对路径

    四、循环导入问题

      问题:由于一个模块在执行的过程中,导入第二个模块,而第二个模块在未完全执行完前又需要导入第一个模块,这就会导致循环导入问题

      解决方案:1.将导入语句放到最后,保证在导入时,所有的名字已经加载入内存

           2.将导入语句放到函数中,只有在函数调用的时候才会执行

    五、编写一个规范的模板

    #!/usr/bin/env python #通常只在类unix环境有效,作用是可以使用脚本名来执行,而无需直接调用解释器。
    
    "The module is used to..." #模块的文档描述
    
    import sys #导入模块
    
    x=1 #定义全局变量,如果非必须,则最好使用局部变量,这样可以提高代码的易维护性,并且可以节省内存提高性能
    
    class Foo: #定义类,并写好类的注释
        'Class Foo is used to...'
        pass
    
    def test(): #定义函数,并写好函数的注释
        'Function test is used to…'
        pass
    
    if __name__ == '__main__': #主程序
        test() #在被当做脚本执行时,执行此处的代码

    六、包的使用

    6.1、包的定义

      包就是一个含有__init__文件的文件夹

    6.2、为什么要有包

      包的本质是一种模块,包是用来当做模块在使用

    6.3、包在使用时发生的事

      1.产生一个名称空间

      2.运行包下的__init__。py文件,将运行中的名字全部导入到名称空间中

      3.在当前执行的文件中遇到的名字,将会直接指向步骤1中的名称空间

    6.4、强调事项

      1.包的导入分为import和from。。。import两种,但不管是哪一种,再导入时都要准守:凡是在导入时带点的,左边必须是一个包。使用时不限制

      2.两个包之间有同一个包也不会冲突,名字分别会在两个名称空间中

      3.import导入文件时,产生的名称空间中的名字来源于文件,

       import包产生的名称空间的名字同样来自文件,即包下的__init__.py,导入包的本质就是在导入文件

     七、包的导入与绝对导入

      包的导入分为绝对导入和相对导入

    7.1、绝对导入

      绝对导入:以顶级包作为起始

    # pool包的__init__.py文件
    from pool.subpool import f1    # 必须从点击包开始
    
    f1()    # 使用

    7.2、包的相对导入

      相对导入:。代表当前文件所在位置     

              。。代表上一级目录所在地址

    #pool下的__init__.py
    from . import versions

    7.3、import的绝对导入

      可以在导入过程中不断的加。导入过程中同样会依次执行包下的__init__.py,只是基于import导入的结果,使用时必须加上该前缀

    #操作pool下的__init__.py,保证pool.futures
    from . import futures #或from pool import futures
    
    #操作futrues下的__init__.py,保证pool.futures.process
    from . import process #或from pool.futures import process

    7.4、注意事项:form 。import是可以的,但是form       import。。是不可以的

           在包内模块之间的导入推荐使用相对导入,但是相对导入只能包模块内,禁止在不同目录下使用包

           无论是import还是 form   import,凡是带点的左边必须是包,否则错误。

    from pool import futures.process #语法错误
    from pool.futures import process #语法正确
  • 相关阅读:
    C#单例模式的多种写法
    数据库优化
    Web Service和Web Api的区别和应用场景
    浅谈堆和栈、值类型和引用类型。
    浅谈隐式类型var和动态类型dynamic以及MVC特性ViewBag
    C# using的三种用法
    sql将表中的某个字段进行排序
    c#重载和重写及运用
    Asp.net Mvc5的认识
    Log4net记录日志存库并存本地
  • 原文地址:https://www.cnblogs.com/jingpeng/p/12595251.html
Copyright © 2011-2022 走看看