模块与包
一、模块
二、包
一、模块
1.import
1.1通过import导入模块后发生的事情:
1.创建名称空间,用来存放导入模块中定义的名字
2.基于刚刚创建的名称空间来执行导入的模块
3.创建名字指向该名称空间,通过模块.的方式调用
#spam.py
print('from spam')
money = 1000
def read1():
print('from:spam-->read1',money)
def read2():
print('from:spam-->read2')
read1()
def change():
global money
money = 0
#test.py
import spam #执行导入模块
money = 123
print(spam.money)
spam.read1()
spam.read2()
spam.change()
print(spam.money)
'''
#执行结果:
from spam
1000
from:spam-->read1 1000
from:spam-->read2
from:spam-->read1 1000
0
'''
1.1为模块起别名:
import 模块 as 别名
#test.py
import spam as s
money = 123
print(s.money)
s.read1()
s.read2()
s.change()
print(s.money)
2.from ... import ...
2.1直接调用:
调用模块时不用加前缀,直接通过名字调用
from 模块 import 属性
#test.py
from spam import read1,read2,change #导入变量和函数,执行时回到spam.py中寻找全局变量money
money = 123 #import 的money被重新绑定到123
print(money)
read1()
read2()
change()
print(money)
‘’‘
#执行结果:
from spam
123
from:spam-->read1 1000
from:spam-->read2
from:spam-->read1 1000
123
’‘’
- 当有import文件中与调用文件有重名函数,则会有覆盖效果
- from 模块 import 属性 as 别名,也支持别名
2.2全部导入
将模块中不是以__开头的名字全部导入
from 模块 import *
#test.py
from spam import *
print(money)
read1()
read2()
change()
print(money)
'''
执行结果:
from spam
1000
from:spam-->read1 1000
from:spam-->read2
from:spam-->read1 1000
1000
'''
* 通常配合__all__使用
spam.py文件中新增一行
__all__ = ['read1'] #test.py文件import spam import * 只能导入read1名字
2.3模块只能用于脚本执行
模块全局变量__name__可以查看模块名称
当前脚本执行__name__结果为__main__
#所以通过
if __name__ == '__main__':
print('执行本脚本才会打印。。')
read1() #当其他文件调用时,不会执行其中代码或者调用的代码
3.模块搜索路径:
模块加载顺序:
1.查找模块,优先从内存(sys.modules)中查找
2.内存中查找不到从内建(built-in)模块中查找
3.内建模块中查找不到从标准库路径(sys.path)查找
追加自己的路径
import sys
sys.path.append('模块路径') #追加到标准库列表尾
sys.path.insert(0,'模块路径') #插入到标准库列头,会优先被搜索到
4.python编译
为了提高模块加载速度,每个模块都会有自己的编译版本存放在__pycache__文件中,如图spam模块编译文件为,spam.cpython-35.pyc,模块名称.cpython3.5版本。
二、包
包的导入可以使用import和from...import...
凡是在导入时带点的,点的左边都必须是包
建立目录结构
1.import
import glance.db.models
glance.db.models.register_models('mysql')
2.from...import...
from后import导入的模块,必须是一个,不能带点
from glance.db import models
models.register_models('mysql')
from glance.db.models import register_models
register_models('mysql')
3.init.py文件
包下都会存在__init__.py文件
只要导入包或者包下任意部分,都会依次执行包下的__init__.py文件,所以文件中可以写入初始化代码
4.from...import *
在__init__.py中定义__all__内容,限制通过*导入模块后,可以访问的模块
#在home/glance/api/__init__.py中定义
x=10
def func():
print('from api.__init.py')
__all__=['x','func','policy'] #限制访问模块
#home/test.py
from glance.api import *
func()
policy.get()
5.绝对导入和相对导入
绝对导入:将要导入的模块的包名写完整
#home/test.py
from glance.cmd import manage #home/glance/cmd/manage.py模块目录
manage.main()
相对导入:使用.或者..的方式作为开头,只适用于同一包中
#home/test.py
from ..cmd import manage #home/glance/cmd/manage.py模块目录
manage.main()
注:import适用于导入内置或者第三方模块,自定义模块最好使用from...import...绝对活着相对导入
6.单独导入包
单独导入包名时,不会把包内其他子包和子模块导入
#在与glance同级的test.py中
import glance
glance.cmd.manage.main()
'''
执行结果:
AttributeError: module 'glance' has no attribute 'cmd'
'''
通过在glance/init.py和glance/cmd/init.py中增加包的引用解决问题
#glance/__init__.py
from . import cmd
#glance/cmd/__init__.py
from . import manage