码迷,mamicode.com
首页 > 编程语言 > 详细

python引用问题

时间:2016-06-08 13:48:40      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

1. 绝对引用,相对引用(absolute_import and relative import)
package/__init__.py
pachage/lala.py
pachage/sys.py

假设在lala.py中import sys,是引用的当前目录的sys, 还是标准库里的sys?来看一下

lala.py

import sys
print str(sys)

 

sys.py, __init__.py都是空文件即可

看一下执行结果

bogon:package licong$ python -m package.lala
<module package.sys from package/sys.pyc>

 

可以知道,python是按照sys.path的优先级去寻找的模块,如果找到就停止加载,而sys.path排在第一个的就是当前目录,所以这就是所谓的隐式的相对引用。

好在python2.5中我们后提供了一种修改这种行为的方法,来看一下

lala.py修改为

from __future__ import absolute_import
import sys
print str(sys)

来看一下结果

bogon:package licong$ python -m package.lala
<module sys (built-in)>

 

区别只是添加了from __future__ import absolute_import这句话

如果我们想用当前目录的sys模块怎么办?可以通过显示的相对引用来解决。

lala.py修改为

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




结果是一样的

python引用问题

标签:

原文地址:http://www.cnblogs.com/selol/p/5569664.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!