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

    导入模块

    总结:

    import

    import 模块名

    import 模块名 as 别名

    import 模块名1,模块名2,模块名3...(不建议)

    from ... import

    from 模块名 import 模块文件里具体的功能名字

    from 模块名 import 模块文件里具体的功能名字 as 别名

    from 模块名 import * (不建议)

    #以下两种仅仅针对*号做设置

    1> 在模块文件里的功能名字前加_下划线  那么*里就不包含此功能 仅仅针对这里的*

    2>在模块文件里设置 __all__['功能名1',“功能名2”...]  仅仅设置的包含在*号里,并不是所有

    举例说明:

    ##重点: 源文件和现文件的名称空间

    模块文件

    spam.py

    #spam.py
    print('from the spam.py')
    
    money=1000
    
    def read1():
        print('spam->read1->money',money)
    
    def read2():
        print('spam->read2 calling read')
        read1()
    
    def change():
        global money
        money=0
    #import导入
    
    import spam
    print(spam.money)
    print(spam.read1()) #调用的时候 需要加模块名作为前缀
    #from ... import  导入
    
    from spam import read1,read2,money
    print(read1())
    print(money) #直接导入功能名字  可以直接调用

    两种方法对比

    import  需要添加前缀,但是不容易和当前文件中的变量混淆

    from ... import  使用源文件的名字时无需添加前缀,方便 但是容易和当前文件中的名字混淆

    查看当然导入的模块

    import sys
    print(sys.modules)

    模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下

    #test.py
    import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
    import spam
    import spam
    import spam
    
    '''
    执行结果:
    from the spam.py
    '''

    导入模块做的事

    1> 执行源文件

    2>以一个源文件的全局名称空间

    3>在当前位置拿到一个模块名,指向源文件的名称空间

    把模块当做脚本执行

    在模块文件的尾部加入以下代码,便于开发者调试,意思是把模块当做脚本执行的时候,才会执行以下代码

    当做模块执行的时候  忽略

    if __name__ == "__main__":
        import sys
        fib(int(sys.argv[1]))

    模块的搜索路径

    python解释器在启动时会自动加载一些模块,可以使用sys.modules查看

    在第一次导入某个模块时(比如spam),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用

    如果没有,解释器则会查找同名的内建模块,如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。

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

    为了防止找不到模块,所以要把自定义的模块加入到sys.path路径中 方法如下

    import sys
    print(sys.path)
    sys.path.append(r'F:untitledac')
    #或者
    sys.path.insert(r'F:untitledac')

    导入包

    重要点:

    1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

    2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

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

    强调:

      1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

      2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

     重要: 一定要搞懂,谁是执行文件,执行文件的路径 就是sys.path第一个要找的路径。

    导入方式

    from 包名(如果有多级目录 包名.二级目录 .三级目录)import 文件名

    理念:包也是一种模块,模块就是为了导入使用的 ,要给使用者提供方便

    举个例子:

    目录结构

    glance/                   #Top-level package
    
    ├── __init__.py      #Initialize the glance package
    
    ├── api                  #Subpackage for api
    
    │   ├── __init__.py
    
    │   ├── policy.py
    
    │   └── versions.py
    
    ├── cmd                #Subpackage for cmd
    
    │   ├── __init__.py
    
    │   └── manage.py
    
                  #Subpackage for db
    
    #文件内容
    
    #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')
    

    如上的目录结构和文件内容,如果想 实现包名.功能名  调用功能的话  那么 glance的 __init__.py  配置如下:

    
    
    from glance.api.versions import create_resource
    from glance.cmd.manage import main
    from glance.api.policy import get
    
    

    那么和glance同级目录的执行文件 就可以这样调用

    import glance
    glance.get()
    glance.create_resource('test.conf')
    glance.main()

    相对导入和绝对导入

    依据上边的例子 继续说 (**执行文件和包是同级目录

    绝对导入的话 glance的 __init__.py  配置如下:

    from glance.api.versions import create_resource
    from glance.cmd.manage import main
    from glance.api.policy import get

    相对导入:

    from .api.versions import create_resource
    from .cmd.manage import main
    from .api.policy import get
    #. 代表当前目录

    现在有一个需求 

    api/policy.py 需要调用 cmd/manage.py里的功能,那么policy.py里需要增加的配置如下:

    绝对导入

    from glance.cmd.manage import main #新增内容
    def get():
        print('from policy.py')
        main() #新增内容 测试代用manage.py里的main功能

    相对导入

    from ..cmd.manage import main #新增内容 .当前目录 ..上一级目录
    def get():
        print('from policy.py')
        main() #新增内容 测试代用manage.py里的main功能

    在执行文件里测试 如下

    import glance
    glance.get()
    '''
    打印结果:
    from policy.py
    from manage.py
    #两个文件的内容都有了
    '''

    以上都是基于 执行文件和包在同一目录级别,如果不在同一目录级别 就需要将包的路径加入 sys.path

    思路:

    导入模块(包)

    1> 执行文件如果不和模块(包)在同一目录,就加入到 sys.path里

    2>如果是包 就在包的init文件里做好 包的导入

     软件开发规范

    常用模块

    点我查看常用模块

  • 相关阅读:
    DEV控件GridControl常用属性设置(转)
    【649】shapely strtree STRtree 构建 RTree
    【648】计算直线间的夹角
    【646】灰度图array转为RGB三通道array
    【645】OpenCV 相关函数说明
    【644】二值图去掉面积小的部分 cv2.threshold
    Makefile中include、-include、sinclude
    openssh交叉编译
    四元数插值
    循环求余法
  • 原文地址:https://www.cnblogs.com/lazyball/p/7269399.html
Copyright © 2011-2022 走看看