1、python代码的目录就称为包,因此这类倒入就称为包导入。事实上,包倒入是把计算机的目录变成另一个python命名空间,而属性则对应目录中所包含的所有子目录和模块文件。
2、用法
import dir1.dir2.mod
其中dir1的顶层目录必须在搜索路径下,也就是说在sys.path里面。还有就是dir1和dir2目录下必须有__init__.py这个文件
3、包的相对倒入
from . import spam #告诉python把位于语句中的文件相同包路径中的名为spam的一个模板导入。
from .spam import name #从名为spam的模板导入变量name,而整个spam模板与包含这条语句的文件位于同一个包下
4、相对导入只针对from有用,对from没用
5、如果mypkg下面有name1,name2模块
from .string import name1,name2 #从mypkg下面的string下面导入name1,name2
from . import string #从mypkg导入string
from .. import string #从mypkg兄弟目录下倒入string
6、例子
位于摩格模块A.B.C中的代码可以做下面任何一种导入
from . import D #import A.B.D
from .. import E #import A.E
from .D import X #import A.B.D.X
from ..E import X #import A.E.X
#高级模块话题
1、把一个下划线放在变量名前(例如:_x),可以防止客户端使from * 语句导入模块名时把其中那些变量复制出去。
__all__可以在模块顶层把变量名的字符串列表赋值给 __all__
2、启用以后的语言特性
from __future__ import featurename
3、混合用法模式:__name__和__main__
如果文件是以顶层程序文件执行的,在启动时,__name__就会设置为字符串 __main__
如果文件被导入,__name__就会改设成客户端所了解的模块名
4、import语句和from语句的as扩展
import modulename as name
相当于
import modulename
name = modulename
del modulename
from modulename import attrname as name
5、因为模块通过 内置属性显示了他们大多数有趣的特性,因此可以很容易的编写 程序来管理其他程序。这类管理程序称为元程序。因为他们是在其他系统 之上工作。这也成为内省。
例如:要取得模块M 中的属性name的集中方法
M.name #点号运算
M.__dict__['name']#对模块的属性字典(在内置__dict__属性中)
sys.modules['M'].name #sys.modules中存在已经加载的模板列表
getattr('M','name') #内置函数getattr
#下面模拟内置函数dir
def mydir(module,verbose=True):
sepline = '-'*60
if verbose:
print(sepline)
print('name:',module.__name__,' file:',module.__file__)
print(sepline)
count = 0
for attr in module.__dict__:
print('%02d) %s'%(count,attr),end=' ')
if attr.startwith('__'):
print('<built-in name>')
else
print(getattr(module,attr))
count+=1
if verbose :
print(sepline)
print(module.__name__,'has %d names' %count)
print(sepline)
6、如果想动态的改变导入模块,则必须通过exec或者eval函数
modname = 'string'
exec('import '+modname)
exec函数编译一个代码字符串,并且将其传递给python解释器以执行。
exec一个真正的缺点是,每次运行时都必须编译 import语句,如果他运行多次,则可以使用内置 __import__函数从一个名称字符串导入,代码可能运行速度更快,效果是类似的。但是__import__运行模块对象,所有这里先赋值给一个名称以保存
modename = 'string'
string = __import__(modename)
7、过渡性模块重载
例如:
如果要 重载摩格模块A,并且A 导入模板B C ,重载只适用于A ,不适用于B 和C,A中导入的B和C的语句 在重载的时候重新运行了 。但是他们只是获得已经重载 B 和C
过渡性重载工具
import types
from imp import reload
def status(module):
print("reloading:",module.__name__)
def transitive_reload(module,visited):
if not module in visited:
status(module)
reload(module)
visited[module] = None
for attrobj in module.__dict__.values():
if type(attrobj) ==types.ModuleType:
transitive_reload(attrobj,visited)
def reloadall(*args):
visited = {}
for arg in args:
if type(arg) == types.ModuleType:
transitive_reload(arg,visited)