# 一、 今日主要内容
# 1. 包
# 包就是一个文件夹. py2中包内必须要有一个__init__.py文件, 在python3中可以省略,但是最好都保留.
# __init__.py 当我们导入一个包的时候,默认执行这个包内的__init__.py
# if 条件:
# 语句块
# 一条语句 > 语句块 > 代码块(函数,类) > py文件(模块) > 包
# 2. 相对导入和绝对导入
# 相对导入: 相对于当前模块所在的包. 使用的时候必须在包外面启动
# 绝对导入: 根据包的根目录去导入内容
#
# 全部都依赖于 sys.path
#
# 3. 使用包要注意的东西
#
# 尽量在包的外面启动程序.
# 二、知识带你补充
# 我们现在知道可以使⽤import和from xxx import xxx来导入⼀个模块中的内容. 那有⼀种
# 特殊的写法: from xxx import * 我们说此时是把模块中的所有内容都导入. 注意, 如果模块中
# 没有写出__all__ 则默认所有内容都导入. 如果写了__all__ 此时导入的内容就是在__all__列表
# 中列出来的所有名字
# policy 模块
# import versions # 这种模式下__all__对其无影响 因为是用模块名去访问函数
# versions.attack()
# versions.he()
# print(versions.a)
#
# from versions import *
# attack() # 你很能打咯
# he() # 报错
#
# # versions 模块
# __all__ = ["a", "attack"]
# def attack():
# print("你很能打咯")
# def he():
# print("我很能喝")
#
# a = 1000
# 三、包
# 包是⼀种通过 '.模块名'来组织python模块名称空间的⽅式. 那什么样的东⻄是包呢? 我
# 们创建的每个⽂件夹都可以被称之为包. 但是我们要注意, 在python2中规定. 包内必须存在
# __init__.py⽂件. 创建包的⽬的不是为了运⾏, ⽽是被导入使⽤. 包只是⼀种形式⽽已. 包的本
# 质就是⼀种模块
# 为何要使⽤包? 包的本质就是⼀个⽂件夹, 那么⽂件夹唯⼀的功能就是将⽂件组织起来,
# 随着功能越写越多, 我们⽆法将所有功能都放在⼀个⽂件中, 于是我们使⽤模块去组织功能,
# 随着模块越来越多, 我们就需要⽤⽂件夹将模块⽂件组织起来, 以此来提⾼程序的结构性和可
# 维护性
# ⾸先, 我们先创建⼀些包. ⽤来作为接下来的学习. 包很好创建. 只要是⼀个⽂件夹, 有
# __init__.py就可以.
# import os
# os.makedirs('glance/api')
# os.makedirs('glance/cmd')
# os.makedirs('glance/db')
# l = []
# l.append(open('glance/__init__.py','w'))
# l.append(open('glance/api/__init__.py','w'))
# l.append(open('glance/api/policy.py','w'))
# l.append(open('glance/api/versions.py','w'))
# l.append(open('glance/cmd/__init__.py','w'))
# l.append(open('glance/cmd/manage.py','w'))
# l.append(open('glance/db/__init__.py','w'))
# l.append(open('glance/db/models.py','w'))
# map(lambda f:f.close() ,l)
# 当我们导入一个包的时候,默认执行这个包内的__init__.py
# 接下来, 我们来看⼀下绝对导入和相对导入, 我们的最顶级包glance是写给别⼈⽤的. 然
# 后再glance包内部也会有彼此之间互相导入的需求, 这时候就⼜绝对导入和相对导入两种⽅
# 式了.
# 1. 绝对导入: 以glance作为起始
# 2. 相对导入: ⽤. 或者..作为起始(.:表示本级目录 ..:表示上级目录)
# 例如, 我们在glance/api/version.py中使⽤glance/cmd/manage.py
# 总结:
# 1、当你在包内想调用包下其他目录的内容,在当前路径加入包的路径(如果不加入包路径则不能访问)
# 当前模块为policy
# 需求:实现policy直接访问manage里的内容(在当前文件sys.path路径下加入包的路径)
# sys.path.insert(0, "E:\python骑士计划\python D26 包") # 在此文件中加入包的根目录
# print(sys.path)
# from glance.cmd import manage
# manage.main() # from manage(加入包的跟目录路径则当前文件有访问包中其他文件夹的权限可以直接访问)
#
# 2、通过和包平级的tast1文件去访问policy,在policy中访问manage,间接实现poiicy访问manage
# 绝对路径访问:
# test1:
# from glance import policy
#
# policy:
# from glance.cmd import manage
# manage.main()
# 3、和包同级的模块可以直接访问包里的任何模块里的所有内容
# os模块应用
# BASE_PATH = os.path.dirname(os.path.dirname(__file__))
# print(BASE_PATH) # E:/python骑士计划/python D26 包/glance # 动态定位当前包所在的目录
# # sys.path.insert(0, )
# # from glance.cmd import manage
#
# print(os.path.abspath(__file__)) # 获取文件当前绝对路径(这里的__file__表示当前文件__file__== "policy.py")
# # E:\python骑士计划\python D26 包\glance\api\policy.py
#
# print(os.path.dirname(__file__)) # 获取当前文件的目录
# # 结果:E:/python骑士计划/python D26 包/glance/api
#
# print(os.path.abspath("policy.py"))
#
# print(sys.path)
# BASE_PATH = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
# sys.path.insert(0, BASE_PATH)
#
# from glance.cmd import manage
# manage.main() # from manage
# 包的注意事项:
# 1. 关于包相关的导入语句也分为import和from xxx import xxx两种, 但⽆论使⽤哪种,
# ⽆论在什么位置, 在导入时都必须遵循⼀个原则: 凡是在导入时带点的. 点左边都必须是⼀
# 个包. 否则报错. 可以带⼀连串的点. 比如a.b.c
# 2. import导入⽂件时. 产⽣名称空间中的名字来源于⽂件, import 包, 产⽣的名称空间
# 中的名字同样来源于⽂件, 即包下的__init__,py, 导入包本质就是在导入该⽂件
# 3. 包A和包B下有同名模块也不会冲突, 如A.a和B.a来⾃两个名称空间