模块与包

一、模块
二、包

一、模块

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版本。
71E8B04F-101A-4685-A857-60C99A820F74

二、包

包的导入可以使用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
posted @ 2017-05-02 18:53  六神酱  阅读(157)  评论(0编辑  收藏  举报