前言
我看到有些文章说的是:
import 模块:导入一个模块;注:相当于导入的是一个文件夹,是个相对路径。
from…import:导入了一个模块中的一个函数;注:相当于导入的是一个文件夹中的文件,是个绝对路径。
这里说from … import 导入的是一个函数,这种说法是不对的。应该是:
from … import … 可以导入包,模块,函数,类或者变量等等;而import 只能导入包或者模块,不能导入其他
具体说明及差异
拿常见的numpy举例。
部分一
以下是numpy一个子包的内容:
在 test_scripts.py 文件中,定义的有几个函数,就拿其中一个 find_f2py_commands() 举例:
测试代码:
from numpy.tests.test_scripts import find_f2py_commands
import numpy.tests.test_scripts.find_f2py_commands
if __name__ == '__main__':
pass
报错信息如下:
ModuleNotFoundError: No module named 'numpy.tests.test_scripts.find_f2py_commands';
'numpy.tests.test_scripts' is not a package
也就是说,在 import a.b.c.xxx时,xxx的上一级c需要是一个包才能正确调用。如果c是一个包,就可以得出,最后一级的xxx只能是c的一个子模块,也就说明了前言中的内容:import 只能导入包或者模块
部分二,__init__.py相关
import … 只能从实际路径相对关系导入包或者模块,而from … import … 还可以导入__init__.py
中声明的包、模块、函数等等
为了测试,我们在numpy.tests路径下的__init__.py文件中添加:import numpy.random as random
,在tests路径中是没有这个包的
测试代码:
from numpy.tests import random
import numpy.tests.random
if __name__ == '__main__':
pass
报错信息如下:
Traceback (most recent call last):
File "d:\Computer_Programming\python\test\test.py", line 7, in <module>
import numpy.tests.random
ModuleNotFoundError: No module named 'numpy.tests.random'
两种方法导入之后的使用说明及差异
from a.b import xxx,这种方法在使用时,直接用xxx即可;
import a.b.xxx,就需要使用a.b.xxx
不过,如果这两种方法导入的都是包,则除了上述的名字差异外,使用上都是相同的,都与xxx路径下__init__.py中导入的信息有关
比如,我们在 numpy.tests 路径中添加一个名为 np_test的文件夹(只需要包含一个__init__.py文件即可,内容无所谓有无):
然后,测试代码:
import numpy.tests as test_a
# from numpy import tests as test_b
# 可以分别注释掉然后测试,报错信息都相同
if __name__ == '__main__':
print(test_a.np_test)
# print(test_b.np_test)
报错信息均为:
AttributeError: module 'numpy.tests' has no attribute 'np_test'
然后修改tests路径下的__init__.py文件,添加:
之后再次重复上述测试,就都输出正常了:
自定义python包和模块
例如,我们自定义的包为np_test,结构如下:
np_test
--__init__.py
--function.py
__init__.py内容如下:
from . import function
function.py内容如下:
def func_a():
print('a')
def func_b():
print('b')
如果自定义的包有一些子包或者子模块,或者想要使用其他已安装的python包(类似上述的random那里)的话,就需要在np_test路径下的__init__.py中进行声明
添加自定义包的存放路径的具体方法见另一篇文章 本文采用的是其中的方法三,将np_test这个自定义包放在了lib\site-packages路径中:
之后就是使用的测试代码:
from np_test import function
import np_test
if __name__ == '__main__':
function.func_a()
np_test.function.func_b()
输出如下,正确:
如果__init__.py文件是空文件的话,则以上方法就会报错,原因上文中有说明。
另外,可以修改__init__.py文件的内容,从而更方便的使用np_test包:
将__init__.py内容修改为:
from . import function
from .function import func_a
from .function import func_b
之后测试,就可以直接使用function模块中的函数,而不需要import function相关信息:
import np_test
if __name__ == '__main__':
np_test.func_a()
np_test.func_b()
输出正确,同上
附注
如果用的是conda,原理类似