anaconda的python的第三方库

这不是一篇关于编程的文章,是从运行的条件来考虑整个软件的分析。anaconda是90%的python代码,那么它所运行的python环境和库到底有那些?import了些什么?这对于安装程序的瘦身是很重要的,也是对认识整个系统环境迈出的第一步!
我不会去急着去看源代码,首先我会去找一个可运行的环境中寻找整个运行流程:
(以下操作均基于asianux3.0)
将第一张光盘中的/image/stage2.img,下载到本地。
#file
stage2.img
stage2.img:
Squashfs filesystem, little endian, version 3.0, 68102631 bytes, 4938
inodes, blocksize: 65536 bytes, created: Wed Aug 29 16:58:29 2007
#mkdir
stage2
#mount
-t squashfs -o loop stage2.img stage2
这就是我们通常看到的整个启动安装的全部程序、配置文件、库文件等
有了这个stage2之后,正如题目所言,此文仅考虑运行anaconda的python环境问题,其它一概不论,在下篇文章我会提到anaconda的启动过程,诸如stage1\stage2\anaconda\rpminstall等等。
#cd stage2
此时可以看到类似我们完成系统的根目录的目录。
$ ls
etc  lib  modules  proc  usr  var
如果你在系统安装的过程中在终端下执行过命令的话,就明白那里的环境变量指的是什么地方了。
我到/usr/bin/下查看anaconda的主程序。当然此anaconda可执行,就代表在此之前的环境变量就设置好了。请参阅后续文章。
在python程序中,先找__main__,类似于c中main,如下:
if __name__ == "__main__":
    anaconda = Anaconda()
    setupPythonPath()
......
setupPythonUpdates()
.......
Anaconda是一个类,在整个程序中有很多地方继承,具体的分析将在以后慢慢的进行,略过这句,看此文的核心内容:
setupPythonPath(),这是一个函数,具体代码如下:
def setupPythonPath():
    # For anaconda in test mode
    if (os.path.exists('isys')):
        sys.path.append('isys')
        sys.path.append('textw')
        sys.path.append('iw')
    else:
        sys.path.append('/usr/lib/anaconda')
        sys.path.append('/usr/lib/anaconda/textw')
        sys.path.append('/usr/lib/anaconda/iw')
    if (os.path.exists('booty')):
        sys.path.append('booty')
        sys.path.append('booty/edd')
    else:
        sys.path.append('/usr/lib/booty')
    sys.path.append('/usr/share/system-config-date')
isys,textw,iw分别为检查系统的程序、运行在text模式下的screen,运行在图形模式时的UI界面。
booty是"""Module for manipulation and creation of boot loader configurations"""
最后添加的变量是设置系统时间的python程序。
setupPythonUpdates(),这是真正的主角。代码如下:
def setupPythonUpdates():
    import glob
#导入glob模块,glob对于熟悉shell的人来说,应该不陌生。
    # get the python version.  first of /usr/lib/python*, strip off the
    # first 15 chars
    pyvers = glob.glob("/usr/lib/python*")
    pyver = pyvers[0][15:]
#利用glog定义python的版本号变量。
    try:
        os.mkdir("/tmp/updates")
    except:
        pass
    for pypkg in ("rhpl", "yum", "rpmUtils", "urlgrabber", "pykickstart",
                  "rhpxl", "pirut"):
        if os.access("/mnt/source/RHupdates/%s" %(pypkg,), os.X_OK):
            try:
                os.mkdir("/tmp/updates/%s" %(pypkg,))
            except:
           pass
#建立rhpl,yum,rpmUtils等目录在stage2运行环境的/tmp/updates目录,
            # symlink the existing ones
            for f in os.listdir("/mnt/source/RHupdates/%s" %(pypkg,)):
                os.symlink("/mnt/source/RHupdates/%s/%s" %(pypkg, f),
                           "/tmp/updates/%s/%s" %(pypkg, f))
        # get the libdir.  *sigh*
        if os.access("/usr/lib64/python%s/site-packages/%s" %(pyver, pypkg),
                     os.X_OK):
            libdir = "lib64"
        elif os.access("/usr/lib/python%s/site-packages/%s" %(pyver, pypkg),
                       os.X_OK):
            libdir = "lib"
        else:
            # If the directory doesn't exist, there's nothing to link over.
            # This happens if we forgot to include one of the above packages
            # in the image, for instance.
            continue
        if os.access("/tmp/updates/%s" %(pypkg,), os.X_OK):
            for f in os.listdir("/usr/%s/python%s/site-packages/%s" %(libdir,
                                                                      pyver,
                                                                      pypkg)):
                if os.access("/tmp/updates/%s/%s" %(pypkg, f), os.R_OK):
                    continue
                elif (f.endswith(".pyc") and
                      os.access("/tmp/updates/%s/%s" %(pypkg, f[:-1]),os.R_OK)):
                    # dont copy .pyc files we are replacing with updates
                    continue
                else:
                    os.symlink("/usr/%s/python%s/site-packages/%s/%s" %(libdir,
                                                                        pyver,
                                                                        pypkg,
                                                                        f),
                               "/tmp/updates/%s/%s" %(pypkg, f))
"rhpl", "yum", "rpmUtils", "urlgrabber", "pykickstart","rhpxl", "pirut"这几个库是python库的第三方的,也就说是python默认不会自动安装的。当然上述的python模块都可以在/usr/lib/python2.4/site-packages中找到。注意此函数对os模块的调用很频繁。这对于linux系统编程来说,这是家常便饭。
os.access,判断文件是否存在,若存在,则返回真。
进入phthon交互式模式,执行如下内容:
import os
dir(os)
os.__doc__看简单的查看os模块的功用。