接着上一篇文章最后的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