Python之模块与包

'''模块导入过程:0.先判断sys.modules字典中查看模块是否已经存在,如存在则不做任何操作
               1.从sys.path路径下找到模块
               2.创建模块的命名空间
               3.把文件中的名字都放到这个命名空间里
'''
# import sys
# print(sys.path)
# import modue1 # import只导入一次,导入时会执行一边模块中的代码,会输出'this is func1'
# print(sys.modules['modue1']) # <module 'modue1' from 'D:\\PYTHON\\Process\\python_learning\\module_pakege\\modue1.py'>
# import modue1 # 没有任何输出
# import modue1 # 没有任何输出

# 模块导入可以改变模块名
# import modue1 as md1
# md1.func1()

'''
编码规则:导入顺序
import 内置模块
import 扩展模块
import 自定义模块
'''

# 可以从模块中的导入方法 -- 注意:当前如果有一个func1函数,且定义在导入后则使用当前的
# def func1():
#     print('current func1')
# from modue1 import func1
# func1() # this is func1

# from modue1 import func1
# def func1():
#     print('current func1')
# func1() # current func1

'''
修改modue1代码为:
# variable = 100
def func1():
    print('this is func1',variable)

if __name__ == '__main__':
    func1()
'''
# from modue1 import func1
# # func1()
# variable = 200
# func1() # NameError: name 'variable' is not defined
# 导入的方法始终调用模块中的边量

# __all__列表的作用
'''
修改modue1:
__all__ = ['variable']
variable = 100
def func1():
    print('this is func1',variable)

if __name__ == '__main__':
    func1()
'''
# from modue1 import *
# print(variable) # 输出100
# func1() # NameError: name 'func1' is not defined

# from modue1 import variable,func1
# print(variable) # 100
# func1() # this is func1 100
# __all__在使用import * 时限制导入在__all__列表中的名字

# 包:包的本质是包含__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/models.py','w'))
# map(lambda f:f.close() ,l)

# 在包外使用包
# 使用import
# import glance.api.policy
# glance.api.policy.get()
# import glance.api.versions
# glance.api.versions.create_resource('test.conf')
# import glance.api.policy.get 抛出异常

# 使用from ... import ...
# from glance.api import policy
# policy.get()
# from glance.api.policy import get
# get()
# from glance import api.policy 抛出异常
# 注意: '.'的左边必须是包,from ... import ...导入时,import后面不能再带'.'

#versions.py
def create_resource(conf):
    print('from version.py: ',conf)

# 绝对导入 -- pycharm 会把当前所在目录以及项目的绝对路径添加倒sys.path中
# import sys
# print(sys.path[0],'\n',sys.path[1])
# from glance.cmd import manage
# manage.main()

# 如何让包可以关联导入
# import glance
# glance.api.policy.get() # AttributeError: module 'glance' has no attribute 'api'

# 利用__init__.py
'''
glance/__init__.py
from glance import api
'''
# import glance
# glance.api.policy.get() # AttributeError: module 'glance.api' has no attribute 'policy'

'''
glance/__init__.py
from glance import api
glance/api/__init__.py
from glance.api import policy
'''
# import glance
# glance.api.policy.get() # from policy.py
'''
导入glance时,执行glance下的__init__.py:from glance import api
所以api也被导入了,api包导入时,glance/api/__init__.py又被执行了
所以policy也被导入了,此时只导入glance则整个包链全部导入了
'''
# 但是绝对导入整个报的结构不能改变,否则导入不成功,例如把api放到glance/newdir下,再次导入则失败了

# 相对导入
'''
glance/__init__.py
from . import api
glance/api/__init__.py
from . import policy
'''
# import glance
# glance.api.policy.get() # from policy.py

# 相对导入可以任意改变包的目录结构,例如把api放到glance/newdir下,再次导入依然可以成功
# import glance
# glance.newdir.api.policy.get() # from policy.py
# 相对导入如果在包的内部无法导入其它模块
# 在policy.py中
# from .. import cmd
# cmd.manage.main() # ValueError: attempted relative import beyond top-level package

参考文档:

https://www.cnblogs.com/Eva-J/articles/7292109.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值