1. 绝对引用,相对引用(absolute_import and relative import)
package/__init__.py
pachage/lala.py
pachage/sys.py
假设在lala.py中import sys,是引用的当前目录的sys, 仍是标准库里的sys?来看一下python
lala.py函数
import sys print str(sys)
sys.py, __init__.py都是空文件便可ui
看一下执行结果spa
bogon:package licong$ python -m package.lala <module 'package.sys' from 'package/sys.pyc'>
能够知道,python是按照sys.path的优先级去寻找的模块,若是找到就中止加载,而sys.path排在第一个的就是当前目录,因此这就是所谓的隐式的相对引用。
好在python2.5中咱们后提供了一种修改这种行为的方法,来看一下code
lala.py修改成blog
from __future__ import absolute_import import sys print str(sys)
来看一下结果get
bogon:package licong$ python -m package.lala <module 'sys' (built-in)>
区别只是添加了from __future__ import absolute_import这句话it
若是咱们想用当前目录的sys模块怎么办?能够经过显示的相对引用来解决。class
lala.py修改成import
from __future__ import absolute_import import sys from . import sys as haha print str(sys) print str(haha)
bogon:package licong$ python -m package.lala <module 'sys' (built-in)> <module 'package.sys' from 'package/sys.pyc'>
总结一下包中的几种引用方法,仍是以例子中的文件结构举例
import package.sys 绝对引用
import package.sys 绝对引用且绑定别名
from package import sys 可替代的绝对引用
import sys 隐式的相对引用
from . import sys 显示的相对引用
2. 循环导入问题
c1.py
from c2 import g def x(): pass
c2.py
from c1 import x def g(): pass
上面这两个文件执行任何一个文件都会报错,缘由拿c1.py举例
1.执行c1,
2.c1第一行须要引用c2中的g,执行c2
3.c2第一行引用c1中的x,执行c1
4.因为c1并无执行完成,x并不存在
5.报错
再举一个更好的例子
a.py:
print "a in" import sys print "b imported: %s" % ("b" in sys.modules, ) import b print "a out"
b.py:
print "b in" import a print "b out" x = 3
执行a.py
$ python a.py a in b imported: False b in a in b imported: True a out b out a out
若是在a.py中添加
print b.x
则会报错
缘由是, x只有在b out后才会存在,而a out后就会执行print b.x,而a out 是在b out 以前的。
解决方法:
1 延迟import
c1.py
from c2 import g def x(): return g() print x()
c2.py
def g(): return 123 from c1 import x
可是,这样修改的前提是g函数不会依赖c1
2. import到写到函数内部
c1.py
def x(): from c2 import g return g() print x()
c2.py
def g(): from c1 import x return 123
这样只有函数执行时,才会加载响应模块,可是若是有多个函数依赖其余模块,就须要写多遍,很是蠢。
3. 包
首先要明确,若是不是在包中,是不应出现相对引用这种状况的。
若是是在包中,上面这个问题是有解决方法的(由于包是一个总体,包的每一个组件单独执行没有任何意义,而非包每一个文件是能够独立执行的)
假设包结构是
package/__init__.py
package/a.py
package/b.py
解决方案1
使用import而不要使用from import
a.py
import package.b def x(): pass def haha(): print package.b.g()
b.py
import package.a def g(): return 123
能够看到,成功了
>>> import package.a >>> package.a <module 'package.a' from 'package/a.pyc'> >>> package.a.haha() 123 >>>
解决方案2
把from import 写到__init__.py中
__init__.py
from . import a, b
a.py
import package def x(): pass def haha(): print package.b.g()
b.py
import package def g(): return 123
结果是同样的