zoukankan      html  css  js  c++  java
  • 包及绝对,相对导入

    概要:

    什么是模块
        一系列功能的集合
        一堆函数放在一个py文件
    为什么用模块
        提高维护性,可读性,减少代码冗余,使代码组织结构更清晰
    四种分类:
        1.自定义,包括第三方
        2.内置的
        3.DLL的c或C++
        4.包
    如何使用:
        import
            1.创建名称空间
            2.执行模块文件
            3.在执行文件中创建一个名称 指向模块的名称空间
        from
            1.创建名称空间
            2.执行模块文件
            3.把模块中的名称复制到当前名称空间
        两种的区别在于第三步
        import m1
        m1.func1()
    
        from m1 import func1
        func1()
        注意:避免名称冲突
    模块搜索顺序
        内存已经加载的 - > 内置的 -> sys.path
        sys.modules可用查看内存已经加载的
        我们经常会操作的是sys.path
    两种执行方式:
        1.作为执行文件
        2.作为模块被导入使用
        在代码中可用使用__name__来区分
    
    包
       是包含一堆模块的文件夹
       本质上就是一个文件夹
       不同的是 包中应该包含__init__.py文件
    为什么使用包?:
        从文件夹级别来组织代码
    
    如何使用:
        与使用模块一样
    
        注意:在导入一个包时 实际上导入的是__init__.py
    
    init的作用
        用于初始化包中的模块
        init中主要做什么?
            导入包中的模块
    包的嵌套
        包里面还有包
    
    绝对导入
        以执行文件的sys.path为起始点
    
    相对导入
        相对于某个模块而言,参照当前所在文件的文件夹为起始开始查找
        .表示当前文件  ..表示上一级 ...再上一级
        注意:相对导入仅用于包内模块的相互导入
            不能超过顶层包
            from 导入时 .点的左边必须是一个包名
            import 后面必须是一个明确的名字

    1.什么是包概念:

         包,也是一种模块,对于使用者而言,使用方式和模块没有任何区别。

      本质上就是一个文件夹,不同之处在于:多了一个__init__.py文件,叫包的初始化 文件

    2.为什么要使用包:

    包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来
    随着功能越写越多,我们无法将所以功能都放到一个文件中,于是我们使用模块去组织功能,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性

    3.如何使用包:

      import 导入模块时发生了三件事情

      1.创建名称空间

      2.执行模块py文件,加载名称

      3.在执行文件中产生新的名称,指向模块

      在导入包的时候,由于包实际上是一个文件夹,所以包中需要提供__init__.py文件,该文件用于代表这个包。

    所以import pack,实际是执行了pack下的__init__.py导入这个名称

     __init__.py文件的作用

      导入该包下的所有模块,这样一来使用包的人,用起来非常简单,无需关心包中的文件结构,只要导入了包,就能使用包中所有功能。

      __init__.py文件应该包含哪些内容?

      不应该包含任何的业务逻辑,仅仅用于导入包中的模块

    注意:所有文件的模块导入都以执行文件sys.path为准

    #1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,
      在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。
                    但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
    #2、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件 #3、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

     导入包:

    import

      单独导入包名称时不会导入包中所有包含的所有子模块,如

    #在与glance同级的test.py中
    import glance
    glance.cmd.manage.main()  #main方法在manage模块中
    
    '''
    执行结果:报错
    AttributeError: module 'glance' has no attribute 'cmd'
    
    '''

      解决办法:

    1 #glance/__init__.py
    2 from . import cmd
    3 
    4 #glance/cmd/__init__.py
    5 from . import manage

      执行:

    1 #在于glance同级的test.py中
    2 import glance
    3 glance.cmd.manage.main()

    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 *

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

    此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:

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

     绝对导入和相对导入:

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

      绝对导入:以执行文件的sys.path作为起始点(执行文件只能用绝对导入

        优点:执行文件和被导入的模块中(被导入的模块中可能也会导入别的模块)都可以使用

        缺点:所有导入都是以sys.path为起始点,导入麻烦

      相对导入:参照当前所在文件的文件夹为起始开始查找(只能在一个包中使用,不能用于不同目录内)

        符号:.代表当前所在文件的文件夹,..代表上一级文件夹,...代表上上一级文件夹

        优点:导入更加简单

        缺点:只能在被导入的模块中使用,不能在执行文件中用,执行文件同级可能有很多文件,导致查找效率低.而包内文件有限,不会存在查找效率问题

      例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py  #cmd和api属于两个并列文件夹

    1 在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()

       测试结果:注意一定要在于glance同级的文件中测试

    1 from glance.api import versions 
  • 相关阅读:
    POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
    SPOJ
    POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串
    POJ3261 Milk Patterns —— 后缀数组 出现k次且可重叠的最长子串
    POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串
    SPOJ
    AC自动机小结
    HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP
    POJ1625 Censored! —— AC自动机 + DP + 大数
    Herding
  • 原文地址:https://www.cnblogs.com/xuechengeng/p/9780445.html
Copyright © 2011-2022 走看看