Python 模块化 from .. import 语句资源搜索顺序 (三)

接着上一篇文章最后的import子句资源搜索顺序,我们来写几个例子了解下。

例一、

#test1.py
x = 123 #test.py
import test1
print(dir())
print(test1.x) 运行结果:
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test1']
123

  import 直接导入模块

#test.py
from test1 import x
print(dir())
print(x) 运行结果:
[..., 'x']
123

  from .. import 部分导入

模块中定义的变量就是该模块的属性,就可以通过本例中的两种方法调用模块中的属性。

例二、

资源搜索顺序: 模块属性 --> 子模块 --> ImportError

|--m (包)
|__init__.py (x=456)
|--x (x是一个子模块)
|--__init__.py #m.__init__.py
x = 456 #m.x.__init__.py
print('x.__init__')
class A():
  pass

  

1)该例子中定义了一个模块m,模块m中定义了一个属性x=456,也定义了一个名为x的子模块,子模块中定义了一个类A。

#test.py
from m import x
print(dir())
print(x) 运行结果:
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'x']
456

  最终匹配到的是m模块下的属性x=456,并没有匹配到m子模块。

2)那我们把模块m的属性x去掉,再来运行test.py文件。

运行结果:
x.__init__
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'x']
<module 'm.x' from 'C:\\python\\m\\x\\__init__.py'>

  可以看到当模块m没有属性x后,接着匹配到了子模块x,并输出了子模块x初始化定义的语句和模块信息。

3)那我们再把子模块也删除,再来运行test.py文件。

运行结果:
Traceback (most recent call last):
File "C:/python/test.py", line 1, in <module>
from m import x
ImportError: cannot import name 'x'

  在没有匹配到属性和子模块时,即抛出了ImportError异常。

总结:

资源搜索顺序:   模块属性 --> 子模块 --> ImportError

上一篇:2004 ACM 成绩转换 两种方法


下一篇:What is Cross Linux From Scratch?