您的位置:首页 > 编程语言 > Python开发

【python学习手册】第23章模块包

2016-03-22 17:39 495 查看
写在前面,一些习题解答和自己想法

习题解答

模块包目录内的__init__.py文件有何用途

用于声明和初始化,当导入模块包时,会执行该文件内的代码


每次引用包的内容时,如何避免重复包的完整路径

使用from 语句可以缩短包的路径

例如包dir1.dir2.dir3.foo

from dirr1.dir2.dir3 import foo

引用的时候,可以只用foo的名称


哪些目录需要init.py文件?

包模块中每个目录都需要该文件,哪怕是空文件。


在什么情况下必须通过import而不能通过from使用包

当你需要导入的包或者变量,和某个变量名称重复时,使用import 语句可以避免命名冲突


from mypkg import spam 和from . import spam有什么差别

前者是绝对导入,后者是相对导入


总结一下模块导入:

模块导入有两种语法形式,一种是import xx.xx.xx

另外一种是 from dir1.dir2 import test test可以是模块,也可以是变量

模块的搜索顺序:

1.程序的主目录 或者叫做CWD
2.PYTHONPATH 环境变量
3.标准库
4.前三者目录下的.pth文件


相对导入和绝对导入

一般的在包的外部,对某个包进行导入时,既可以使用from 也可以使用import,不可以用 点(.) ,按照上面的搜索规则进行搜索。

下面仅仅是包的内部进行导入时会发生的一些规则变化,自己编写包的时候需要注意到:

在包的内部进行导入时,增加了相对导入,使得可以显式的仅导入包内相对目录的某个包,例如
from . import apple


而没有 点(.)的时候,py2.6就会先搜索相对路径,再搜索绝对路径 (也是先CWD再其他目录)。

这样就存在一个问题,如果不想搜索相对路径,直接搜索绝对路径或者标准库,就做不到的。

如果是要在包内导入某个标准库string,包内的相对路径也是string

这个让我想到一个例子,有助于理解

import apple 就是我要吃苹果,一般都是先吃手里的,再去商店买

from . import apple  就是只吃自己手里的苹果

如果想直接去商店买,是不行的。


python3就做出了修改:

包的内部进行导入时,忽略包内
import apple 会直接找商店买


python2 如果也想这样,加入下面这一句就可以:

from __future__ import absolute_import


code1

在2.7.10和3.5.1同时测试

包外导入(没有区别):

test\string.py

print("string " * 4)


test\run.py

import string
print(string)


run

python run.py
string string string string
<module 'string' from '/root/py30/test/string.py'>


执行过程,先从主目录也就是run.py所在目录找模块

code2

删一下当前目录下的所有文件
rm -rf string.py


包内导入:

test\pkg\__init__.py

#This is pkg module


test\pkg\string.py

    print("string " * 4)


test\pkg\egg.py

    import string
print(string)


test\run.py

import pkg.egg
print("run")


python2.7:

python run.py
string string string string
<module 'pkg.string' from '/root/py30/test/pkg/string.py'>


python3.5:

python run.py
<module 'string' from '/root/.pyenv/versions/3.5.1/lib/python3.5/string.py'>


注意到,python3 在包内执行语句
import string
的时候,直接忽略了包内的string.py。

就是直接去商店,不吃自己家的。

append code3

加入一个文件

包内导入:

test\pkg\__init__.py

#This is pkg module


test\pkg\string.py

    print("string " * 4)


test\pkg\egg.py

    import string
print(string)


test\string.py

print(“this is cwd string module”)

test\run.py

import pkg.egg
print("run")


python2.7:

python run.py
string string string string
<module 'pkg.string' from '/root/py30/test/pkg/string.py'>


python3.5:

python run.py
this is cwd string module
<module 'string' from '/root/py30/test/string.py'>

注意到,python3 虽然忽略了包内的string.py,然后从cwd开始找,就是程序主目录(见模块的搜索顺序)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: