导入模块和包

总结

模块就是有代码的py文件;

模块myfile.py

'''
@File       : myfile.py
@Time       : 2019/10/10
@Author     : chenzl
@Version    : 1.0
@Contact    : [email protected]
@License    : CC
@Desc       : None
'''
title = "Hello World"

运行的py文件,称为脚本;

脚本test.py

'''
@File       : test.py
@Time       : 2019/10/10
@Author     : chenzl
@Version    : 1.0
@Contact    : [email protected]
@License    : CC
@Desc       : the py script to run
'''

import myfile
print(myfile.title)

myfile.py和test.py要在同一个目录下;

运行脚本

$ python test.py

import

使用import,导入模块myfile到test命令空间;

import导入会有三个步骤:

  • 在sys.path中寻找模块名
  • 编译为字节码(pyc)
  • 运行模块

sys.path会组合4种路径

  • 当前目录
  • PYTHONPATH目录
  • 标准链接库目录
  • pth文件指定的路径

导入的模块,信息存储在sys.modules中;
导入相同的模块,就会直接读取内存中的缓存;

命名空间

每个模块文件是一个独立完备的变量名,即一个命名空间;

如模块myfile,是myfile命名空间,模块内的变量名title是属性于myfile命名空间;

模块test,是test命名空间,import语句将myfile空间导入到test空间,所有要用.访问;

from…import…

使用from...import...,不导入整个模块空间,而只导入空间内的某些变量;

'''
@File       : test.py
@Time       : 2019/10/10
@Author     : chenzl
@Version    : 1.0
@Contact    : [email protected]
@License    : CC
@Desc       : the py script to run
'''

from myfile import title
print(title)

这里说的导入,实质是复制变量名;

从myfile空间,导入(复制)变量title到test空间,就可以直接调用了;

运行脚本

$ python test.py

from * 语句,把模块中所有变量名复制到当前的命名空间(作用域)之内;
因为会使变量来源变得模糊,一般建议一个模块只用一次;

总结: import和from 是赋值语句

导入链

即模块a(a.py)导入模块b(b.py); 模块(b.py)导入模块c(c.py);

模块a调用模块c的变量x,使用

import b
print(b.c.x)

可以看出, import是复制了整个命名空间;
这样就可以互相导入,就是模块c导入模块b;

导入链的命名空间,是一个树形结构;

导入链中,模块a不能直接

import b.c

因为.操作符在导入语句中,会被特殊地解析成路径分隔符;
这就涉及到了"包导入";

: 就是含有__init__.py的目录,可以用来导入;
没有__init__.py的就会当成普通目录,不能使用from...import导入,但是可以用import导入,相当于创建一个普通目录名的命名空间;

导入包时,会自动执行__init__.py,所有一般用来初始化包;也可以为空;
类似模块的文件名是空间名, 包名也是命名空间的名称;

__init__.py里的所有变量,都属于包命名空间;
目录下的所有包和模块,都属于这个包空间下;

如果父目录chenzl有__init__.py为包, 子目录test没有__init__.py为普通目录,可以使用import chenzl.testfrom chenzl import test 导入,相当于创建命名空间chenzl.test

$ mkdir -p chenzl/test
$ touch chenzl/__init__.py
$ vi test.py
import chenzl.test
print(chenzl.test)

$ python test.py


$ vi test.py
from chenzl import test
print(test)

$ python test.py

包内模块的导入

查看__init__.py内容

from .core import *

包内模块的导入有两种方式

  • 绝对搜索
  • 相对搜索

python2.6是默认先相对再绝对的搜索路径顺序;
pyhton3 会明确区分是绝对还是相对的搜索;

绝对搜索,类似模块的导入,是从搜索路径中去寻找模块

from anki.consts import *

python3中的绝对导入,只会在sys.path中寻找,.解析成目录分隔符;忽略包目录;

相对搜索

from . import spam
from .core import *

python3中的相对导入,只会在包内搜索,.解析成当前目录;

import的都是绝对导入,忽略包目录

你可能感兴趣的:(Python)