anaconda的python的第三方库
适兕
|
1#
适兕 发表于 2008-06-15 23:40
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模块的功用。 |