【1.2】模块管理-2-python模块的导入(import)
Python,一个.py文件就构成一个模块。最近写多个py的时候时不时需要调用自己之前写模块,每次都是粘贴复制,最大的问题,就是有的自己写的模块最后修改了,都不知道修改的是哪一个,既然出现了这样的问题,那么我们就来看一下模块应该如何管理。
一 引入模块
我们先写一个first.py文件,内容如下:
def laugh():
print 'HaHaHaHa'
再写一个second.py,并引入first中的程序:
import first
for i in range(10):
first.laugh()
在second.py中,我们使用了first.py中定义的laugh()函数。
引入模块后,可以通过模块.对象的方式来调用引入模块中的某个对象。上面例子中,first为引入的模块,laugh()是我们所引入的对象。
Python中还有其它的引入方式:
1.引入模块a,并将模块a重命名为b
import a as b
2.从模块a中引入function1对象。调用a中对象时,我们不用再说明模块,即直接使用function1,而不是a.function1。
from a import function1
3.从模块a中引入所有对象。调用a中对象时,我们不用再说明模块,即直接使用对象,而不是a.对象。
from a import *
这些引用方式,可以方便后面的程序书写。
显示模块aa中含有的函数:
dir(aa)
二、搜索路径
Python会在以下路径中搜索它想要寻找的模块:
- 程序所在的文件夹
- 操作系统环境变量PYTHONPATH所包含的路径
- 标准库的安装路径
如果你有自定义的模块,或者下载的模块,可以根据情况放在相应的路径,以便Python可以找到。
三 模块包
可以将功能相似的模块放在同一个文件夹(比如说this_dir)中,构成一个模块包。通过
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
引入this_dir文件夹中的module模块。
import this_dir.module
该文件夹中必须包含一个__init__.py的文件,提醒Python,该文件夹为一个模块包。init.py可以是一个空文件。上面的每一级别文件夹下都得加__init__.py
import sound.effects.echo
from sound.effects import echo
from sound.effects.echo import echofilter
四、添加PYTHONPATH到环境变量中
方法一
把/home/lxc/software/program/python添加到PYTHONPATH,语法与shell里面的PATH一样:
export PYTHONPATH=$PYTHONPATH:/home/lxc/software/program/python
就跟改一般的环境变量一样,在.bashrc之类的的文件中添加
export PYTHONPATH=/home/vi:$PYTHONPATH
然后终端中 source .bashrc
方法二
在python脚本里面,使用那些不在PYTHONPATH上的第三方包或是自己编写的模块。 以使用/home/lxc/software/program/python/getopt_exam.py为例。(好用)
$python
>>>import sys
>>>sys.path.append(“/home/lxc/software/program/python”)
>>>import getopt_exam
>>>getopt_exam.version()
version v1.0
>>>
五、我采用的策略
因为不具有管理员权限,没法在根目录下放置__init__.py,就只有通过添加我的模块所在的文件夹到PYTHONPATH中去,然后
# sys.path.append("/home/qqin/project/packages/")
try:
from packages.cal_kmer import *
except ImportError:
from cal_kmer import *
# from packages.cal_kmer import *
这么写,主要是为了在Pycharm调用其他文件夹下的Modules的时候,不会出现pycharm不识别,调用的函数到处出现红色波浪线的问题。
从其他位置调用脚本,但是脚本位置依赖目前这个脚本的位置时:
folder_here = os.path.dirname(os.path.realpath(__file__))
print folder_here
print folder_here[:-3]
sys.path.insert(0, folder_here[:-3])
from genoprime.Calculate_primer import PrimerCalculater
#该脚本在bin文件夹下,而调用的脚本的上一级文件夹genoprime跟bin在同一个文件夹内
六、报错
6.1 提示模块版本不对应
报错信息:
"Matplotlib requires six>=1.10; you have %s" % six.__version__)
ImportError: Matplotlib requires six>=1.10; you have 1.9.0
问题的原因;
- 版本需要升级
- python调包的路径需要修改
问题一的解决办法:
查看six的版本
pip list |grep six
1.11.0
如果版本有问题,可以通过如下方法:
升级: pip install -U six
卸载: pip uninstall six
重新安装: pip install six
很显然,我这不是版本的问题。
-
python调包的路径需要修改
python
print six.version 1.9.0
果然,python用的是就版本的six
先查看一下python的路径
[sam@c01 scripts]$ which python
/data/software/anaconda2/bin/python
接着查看six的路径
python
import six
import sys
print sys.modules['six']
<module 'six' from '/usr/lib/python2.7/site-packages/six.py'>
很明想,这不是我最新版的six的路径,删掉即可:
rm /usr/lib/python2.7/site-packages/six.py
接着运行程序的时候,又有其他的报错:
ImportError: Matplotlib requires pyparsing>=2.0.1; you have 1.5.6
[sam@c01 scripts]$ pip uninstall pyparsing
Cannot uninstall 'pyparsing'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
同理,在python,print print sys.modules[‘pyparsing’],删掉对应的文件即可
rm /usr/lib/python2.7/site-packages/pyparsing.py
然后再重新安装
6.2 案例二
报错:
"ImportError: No module named 'requests.packages.urllib3'"
解决办法:
删除requests
pip uninstall requests
删除以后
pip list |grep requests
还能看到requests
pip show requests
看到了另一个版本的requets
cd 到那个文件夹,然后删掉
然后import requests的时候,报错:
import urllib3 导入不成功
解决办法:
pip show urllib3 找到urllib3的位置,
cd /usr/lib/python2.7/site-packages
sudo rm -r urllib3*
sudo pip install urllib3
原来还是不同位置安装的包的冲突。。
七、总结
import module
module.object
__init__.py
使用print dir() 显示目前已经导入的模块
参考资料
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn