• 导入包与模块


    import os
    os.makedirs('glance/api')
    os.makedirs('glance/cmd')
    os.makedirs('glance/db')
    ls = []
    ls.append(open('glance/__init__.py','w'))
    ls.append(open('glance/api/__init__.py','w'))
    ls.append(open('glance/api/policy.py','w'))
    ls.append(open('glance/api/versions.py','w'))
    ls.append(open('glance/cmd/__init__.py','w'))
    ls.append(open('glance/cmd/manage.py','w'))
    ls.append(open('glance/db/__init__.py','w'))
    ls.append(open('glance/db/models.py','w'))
    map(lambda f: f.close() , ls)
    View Code
    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
    View Code
    #各文件内容
    
    #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')
    
    #models.py
    def register_models(engine):
        print('from models.py: ',engine)
    money = 1000
    
    def read1():
        print('from the models->read1->money', money)
    
    def read2():
        print('from the models->read2 calling read1')
        read1()
    
    def change():
        global money
        money = 60
    View Code
    '''
    层级关系:
    test.py
    模块名A
    包名1/包名2/包名3/模块名B/变量名+函数名
    '''
    
    # 在测试文件test.py中
    # 可以写 import 包名1
    # 可以写 import 模块名A
    # 可以写 from 包名1.包名2 import 包名3
    # 可以写 from 包名1.包名2.包名3 import 模块名
    # 可以写 from 包名1.包名2.包名3.模块名 import 函数名 或 变量名
    '''
    # 错误写法  import 包名.包名.包名.模块名.函数名 或 变量名
    # 错误写法  from 包名.包名 import 包名.模块名
    '''
    
    
    '''
    层级关系:
    test.py
    包名0/包名1/包名2/包名3/模块名B/变量名+函数名
    '''
    # 在测试文件test.py中
    # 不可以写 from 包名1.包名2.包名3 import 模块名B
    # 不可以写 import 包名1
    # python解读此语句后 先进行路径下的模块查找 即从test.py的[sys.path]路径中查找 包名1
    # 和test.py所在目录同级的是包名0 因此会报错 ModuleNotFoundError: No module named '包名1'
    
    
    
    
    
    # 假设以test.py文件的执行 做为程序运行的入口,且当前各__init__.py文件的内容为空
    # 此时test.py文件的工作目录路径被写入系统的[sys.path],且作为路径列表中的第一个元素
    # 当然,如果你是用PyCharm,PyCharm还会自动补充当前路径的父一级目录 做为[sys.path]路径列表的第二个元素
    
    
    # "导入工作"的内容1 —— 将被导入的对象 记录于 {sys.modules} 字典
    # "导入工作"的内容2 —— 执行文件(包的__init__.py文件 或 模块名.py文件)
    # "导入工作"的内容3 —— 创建模块的名字空间 且将'名字'导入到执行入口所在的当前名字空间中
    
    # 例1 import glance.db.models 导入的对象是三个 glance  glance.db  glance.db.models
    # 例2 from glance.db import models 导入的对象是三个 glance  glance.db  glance.db.models
    # 例3 from glance.db.models import register_models 导入的对象还是三个 glance  glance.db  glance.db.models
    # 例4 import glance  导入的对象只一个 glance
    # 以上例子 我们都显式可见地,仅通过写法就可知{sys.modules}字典中因Import导入新增了哪几个对象
    # 你可以用print(sys.modules)去验证,仔细观察你会发现,每个新增对象都从其名字上描述了自己的所属
    '''
    glance
    glance.db
    glance.db.models
    '''
    # 这种层级关系的另一处体现是,各包的__init__.py文件 和 模块名.py文件在被执行时,存在了调用先后顺序
    # 这里补充一下,.py文件能被python执行的前提是 python能依据路径访问到此文件
    # 而路径的成功访问基础是  sys.path + 向下的层级关系
    '''
    test.py文件一直是我们执行的入口,在此文件中打印一下sys.path路径列表吧
    python是以此路径为基础, 以包和包下模块的层级关系为辅助,访问查找被导入的包或模块的py文件并执行它们的
    '''
    
    # 它们的执行被顺序体现如下
    # 例 import glance
    '''
    只执行
    ======glance init 包的初始化========
    '''
    # 例 import glance.db.models
    # 例 from glance.db import models
    # 例 from glance.db.models import register_models
    '''
    都遵循下面的执行顺序
    ======glance init 包的初始化========
    ======db init 包的初始化========
    ====models.py==模块文件被执行====
    '''
    
    # 题外话
    # 一旦{sys.modules}字典包与包、包与模块间的层级关系的明确
    # PyCharm工具软件就可以协助我们在书写代码时,通过按键'.' 关联显示出其备选项
    # 例 import glance.db.models
    # glance.db.models.register_models('mysql') 可被通过按'.'键被快速写出,且可被执行
    
    '''
    思考问题
    test.py文件中 只写import glance
    让glance.db.models.register_models('mysql')在该文件中被成功执行
    实践后,你会发现报错 AttributeError: module 'glance' has no attribute 'db'
    test.py文件中 将import glance 改为 import glance.db.models
    再次实践 会发现 glance.db.models.register_models('mysql')被成功执行
    借助两次实践过程中print(sys.modules)的对比结果 你会找到原因
    '''
    
    # 解决办法
    # 必须在{sys.modules} 字典中 在只有对象glance的基础上 再补充上如下两个对象 glance.db glance.db.models
    # 要写为{sys.modules} 字典新增对象 我们就必须令
    # import glance.db  或 from glance import db
    # import glance.db.models 或 from glance.db import models
    # 这样的语句被执行, 而这样的语句我们又不想写在test.py文件中( 题目是 test.py文件中只写import glance 这一句)
    # 那么 我们可以借助包的初始化文件__init__.py的被执行
    
    '''
    # 在glance包的__init__.py文件中 写如下代码
    # from glance import db
    # 这句代码的执行 使得{sys.modules}字典可以新增 glance.db
    # 这句代码的执行 还使得 db包的初始化文件的也被执行
    # 因此 我们在db包的__init__.py文件中 再次写如下代码
    # from glance.db import models
    # 则{sys.modules}字典可以再次新增 glance.db.models
    # 且模块文件models.py文件会被执行
    # 至此, 'glance'  'glance.db'  'glance.db.models' 这三项都存在于{sys.modules}字典中
    # test.py文件中虽只写了一句 import glance,
    # 但glance.db.models.register_models('mysql')已经可以被执行了
    '''
    
    
    # import"导入工作"结束后的使用,其核心就是 只能使用当前名字空间中新导入的'名字'
    
    # 你可以查看globals()
    # 你可以借助print(directory()) 对比查看执行入口test.py文件的当前名字空间中名字的变化
    '''
    # 例1 import glance 当前名字空间中引入了 一个新名字glance 这是一个包名
    # 例2 import glance.db.models 当前名字空间中引入了 一个新名字glance 这是一个包名
    # 例3 from glance.db import models 当前名字空间中引入了 一个新名字models 这是一个模块名
    # 例4 from glance.db.models import register_models  引入了 一个新名字 register_models 函数名
    '''
    
    # 只要名字存在 该名字就可以被直接拿来使用
    '''
    # 针对例1 直接用glance做代码书写的起始开头 如果 {sys.modules} 字典中 glance  glance.db glance.db.models 都存在
    # 则可以执行 glance.db.models.register_models('mysql')
    # 针对例2 直接用glance做代码书写的起始开头 glance.db.models.register_models('mysql')
    # 针对例3 直接用models做代码书写的起始开头 models.register_models('mysql')
    # 针对例3 直接用register_models做代码书写的起始开头 register_models('mysql')
    '''
    
    # 上述代码被执行时,函数register_models都是回到 模块models.py自身的名字空间内执行
    # 即模块文件内的函数,都以文件的名称空间做为全局名称空间
    # 模块models.py自身的名字空间  对内自称为__main__  对外被称呼为__models__
  • 相关阅读:
    SERU最佳需求分析方法
    需求规格说明书(Volere版)
    开发设计模式之设计六大原则
    清晰、高效、一致、美观 – 关于设计原则的优先级排序
    一个案例,三个角色,简单说下B端产品的权限设计
    如何从0到1打造一个完美的业务系统?
    MarkdownPad2.5 注册码
    WEBSTORM快捷键
    jQuery
    BOM与DOM
  • 原文地址:https://www.cnblogs.com/cherry2020/p/12859729.html
Copyright © 2020-2023  润新知