昨天和今天上午一直在改写基础东西,作为Python的新手,运行程序的时候总会出现:pycharm报错:ModuleNotFoundError: No module named 'XXX',个人觉得首先要分清楚import的是标准库还是自定义模块,为了之后出现重复的错误,特写此博客方便以后查询。主要包含以下几个方面:
目录
1.Python标准库有哪些?
2.本地库的引用(指自己创建的或是别人的模块)
3.为什么要使用模块
4.学习Python中sys.path的使用
5.常用的sys.path汇总
6.个人体会:
:
Python标准库文件,Python标准库概览
如果需要,大家可以查看Python标准库文件。Python语言参考
例如:
os模块提供了与操作系统相关联的函数。
glob模块提供了一个函数用于从目录通配符搜索中生成文件列表;
re模块为高级字符串处理提供了正则表达式工具。对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案;
math模块为浮点运算提供了对底层C函数库的访问:
random提供了生成随机数的工具。
这里解释一下,所谓的模块就是就是一个包含了一组功能的python文件,比如spam.py,模块名为spam,可以通过import spam使用。
首先看一下目录结构,如图所示:
在此示例中,ClusterWordGraph.py是主文件,它要导入的是它当前目录的父目录下的一个子目录中的一个目录中的文件和它统一个目录下的另一个文件 。
在Python3中执行以下导入可能在引用自己文件时会报错:
import commons.wordVector as wordVector
import numpy as np
from keywords.graph.WordGraph import WordGraph
from keywords.graph.PageRankGraph import PageRankGraph
from commons.log import get_logger
from sklearn.cluster import KMeans
于是我通过引入sys模块导入绝对路径,因此应该改写成如下:
import sys
sys.path.append('D:\\pyworkspace\\11\\python_KeyExtractor\\commons')
import WordGraph
import SegmentFactory
sys.path.append('D:\\pyworkspace\\11\\python_KeyExtractor\\keywords\\graph')
import PageRankGraph
import WordNode
import SpecifiedWeight
from log import get_logger
在不知道自己主文件的路径时,可以通过以下代码获得当前所处文件夹的相对路径和绝对路径:
import os
path1=os.path.abspath('.') # 表示当前所处的文件夹的绝对路径
print(path1)
path2=os.path.abspath('..') # 表示当前所处的文件夹上一级文件夹的绝对路径
print(path2)
运行可以得到如下:
D:\pyworkspace\11\python_KeyExtractor\keywords\graph
D:\pyworkspace\11\python_KeyExtractor\keywords
(1)便于管理
随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用
(2)提升开发效率
同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率
如果执行文件和模块不在同一目录,import是找不到自定义模块的,譬如上图中的主文件和要引用的模块就不在同一目录下,因此我们导入自定义模块的步骤如下:
step1:先导入sys模块(Python内置的);
step2:通过sys.path.append(path)
函数来导入自定义模块所在的目录(path可以是相对路径也可以是绝对路径)
step3:导入自定义模块。
Python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的路径。
下面将具体介绍几种常用情况:
(1)主程序与模块程序在同一目录下:
如下面程序结构:
– src
|– mod1.py
|– test1.py
若在程序test1.py中导入模块mod1, 则直接使用import mod1或from mod1 import *;
(2)主程序所在目录是模块所在目录的父(或祖辈)目录
如下面程序结构:
– src
|– mod1.py
|– mod2
| – mod2.py
– test1.py
若在程序test1.py中导入模块mod2, 需要在mod2文件夹中建立空文件__init__.py文件(也可以在该文件中自定义输出模块接口); 然后使用 from mod2.mod2 import * 或import mod2.mod2.
(3)主程序导入上层目录中模块或其他目录(平级)下的模块
如下面程序结构:
– src
|– mod1.py
|– mod2
|– mod2.py
|– sub
| – test2.py
– test1.py
若在程序test2.py中导入模块mod1.py和mod2.py。首先需要在mod2下建立__init__.py文件(同(2)),src下不必建立该文件。然后调用方式如下:
下面程序执行方式均在程序文件所在目录下执行,如test2.py是在cd sub;之后执行python test2.py
而test1.py是在cd src;之后执行python test1.py; 不保证在src目录下执行python sub/test2.py成功。
import sys
sys.path.append(“..”)
import mod1
import mod2.mod2
(4)从(3)可以看出,导入模块关键是能够根据sys.path环境变量的值,找到具体模块的路径。
如果要导入的文件与被执行文件在同一文件夹下,那么直接import即可;
如果不在同一文件夹下,就要一级一级找,跳到这个被引用文件的父级,从父级一级一级写成绝对路径,类似于要导入你D盘的数据文件一样,直到到达你要导入的模块