zoukankan      html  css  js  c++  java
  • 包是一种通过使用‘模块名’来组织python模块名称空间的方式 
    1、无论import形式还是from ... import 形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要在第一时间提高警觉:这是关于包才有的导入语法
    2、包是目录级别的(文件夹级别),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)
    3、import导入文件时,产生名称空间中的名字来源于文件,import包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
    4、.的左边肯定必须是包 #import glance.a.b.c #glance和a和b肯定是包,c不一定 导入包必须使用from 包名
    5、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
    
    └── db                  #Subpackage for db
    
        ├── __init__.py
    
        └── models.py 
    
    1、import
    import glance.db.models
    glance.db.models.register_models('mysql') 
    

     2、from ... import

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

    from glance.db import models
    models.register_models('mysql')
    
    from glance.db.models import register_models
    register_models('mysql')
    

    3、__init__.py文件

    不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。

    4、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同级的文件中执行from glance.api import *就导入__all__中的内容(versions仍然不能导入)。

    5、绝对导入和相对导入

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

    绝对导入:以glance作为起始

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

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

    在glance/api/version.py
    
    #绝对导入
    from glance.cmd import manage
    manage.main()
    
    #相对导入
    from ..cmd import manage
    manage.main()
    

     特别需要注意的是:可以用import导入内置或者第三方模块(已经在sys.path中),但是要绝对避免使用import来导入自定义包的子模块(没有在sys.path中),应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式。

    from glance.api import versions
    
    '''
    执行结果:
    ImportError: No module named 'policy'
    '''
    
    '''
    分析:
    此时我们导入versions在versions.py中执行
    import policy需要找从sys.path也就是从当前目录找policy.py,
    这必然是找不到的
    '''
    

    6、单独导入包

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

    #在与glance同级的test.py中
    import glance
    glance.cmd.manage.main()
    
    '''
    执行结果:
    AttributeError: module 'glance' has no attribute 'cmd'
    
    '''
    
    #glance/__init__.py
    from . import cmd
     
    #glance/cmd/__init__.py
    from . import manage
    

    __all__不能解决吗,__all__是用于控制from...import *

    
    
  • 相关阅读:
    数据库为什么要分区分表
    搜索时 搜索条件在被搜索范围内
    Spring RestTemplet https请求
    微信三方平台接入
    在安装RedisDesktopManager的时候遇到 .dll文件缺失解决办法
    Spring中常见的设计模式——装饰者模式
    Spring中常见的设计模式——适配器模式
    Spring中常见的设计模式——模板模式
    Spring中常见的设计模式——策略模式
    Spring中常见的设计模式——代理模式
  • 原文地址:https://www.cnblogs.com/wangkc/p/6936887.html
Copyright © 2011-2022 走看看