【1】模块管理-2-python模块的导入(import)

在Python中,一个.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中还有其它的引入方式,

#引入模块a,并将模块a重命名为b

import a as b 

从模块a中引入function1对象。调用a中对象时,我们不用再说明模块,即直接使用function1,而不是a.function1。

from a import function1 

从模块a中引入所有对象。调用a中对象时,我们不用再说明模块,即直接使用对象,而不是a.对象。

from a import * 

这些引用方式,可以方便后面的程序书写。

dir(aa) 显示模块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在同一个文件夹内

六、报错:

报错:提示python版本不对应

"Matplotlib requires six>=1.10; you have %s" % six.__version__)

ImportError: Matplotlib requires six>=1.10; you have 1.9.0

问题的原因;

  1. 版本需要升级
  2. python调包的路径需要修改

问题一的解决办法:

查看six的版本

pip list |grep six

1.11.0 

如果版本有问题,可以通过如下方法:

升级: pip install -U six
卸载: pip uninstall six
重新安装: pip install six

很显然,我这不是版本的问题。

  1. 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 

然后再重新安装

案例二

报错:

"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() 显示目前已经导入的模块

参考资料

http://www.cnblogs.com/vamei/archive/2012/07/03/2574436.html

个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn

Sam avatar
About Sam
专注生物信息 专注转化医学