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 
  • 相关阅读:
    CHOCBase
    iOS 12中无法获取WiFi的SSID了?
    如何打开Assets.car文件
    博客园美化资源网站链接
    xcode工程配置绝对路径与相对路径
    UIControl事件
    UIButton属性
    UIAlertView
    UIActivityIndicatorView
    NSAttributedString
  • 原文地址:https://www.cnblogs.com/xuechengeng/p/9780445.html
Copyright © 2011-2022 走看看