python.org发布能与苹果框架构建兼容吗?
(非常抱歉没有提供合适的链接;系统不允许我添加超过两个链接。)
不幸的是,我是通过艰难的方式学到的,不应该随便动Mac OS X(特别是10.6.8)中的默认Python安装。
在使用python.org提供的2.6.6版本(http://www.python.org/getit/releases/2.6.6/)和2.5.4版本(http://www.python.org/getit/releases/2.5.4/)后,我得到了比苹果提供的版本更成熟的Python版本(这对开发很有帮助),但却破坏了系统的核心功能(这对其他事情来说就很糟糕了)。到目前为止,最明显的问题是在尝试运行namebench(https://code.google.com/p/namebench/)、Blink(http://icanblink.com/)和Mercurial(https://www.mercurial-scm.org/)时出现的。从我了解到的情况来看,问题出在路径设置上。
在默认安装中,路径应该类似于这个问题中提到的那样。可是,我的路径看起来是这样的:
$ /usr/bin/python2.6 -V
Python 2.6.6
$ which python
/usr/bin/python
$ python
Python 2.6.6 (r266:84374, Aug 31 2010, 11:00:51)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> for i in sys.path:
... print i
...
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pip-1.0.2-py2.6.egg
/Library/Frameworks/Python.framework/Versions/2.6/lib/python26.zip
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-old
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages
(2.5的情况也差不多,但为了简单起见,我就只说2.6的。)
问题似乎在于没有包含以下路径:
- /Library/Python/2.6/site-packages/*.egg
- /Library/Python/2.6/site-packages
- /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6
- /System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python
这就解释了为什么Blink和namebench找不到PyObjC(PyObjC在OSX SL上预装了吗?),而Mercurial找不到它的模块(在/Library/Python/2.6中)。
Python的错误追踪器中的问题#4865部分解决了这个特定问题,这个问题在2.7及更高版本中已经修复。但因为这是“一个功能请求而不是错误修复”,所以没有回溯到2.5和2.6版本。即便如此,从提交的修复来看(http://hg.python.org/lookup/r70778),我不确定它是否解决了对“Extras”目录缺少引用的问题。
我知道可以通过手动修改site.py来手动添加路径到Python中。我也可以使用PYTHONPATH环境变量。但我不想通过修改site.py来造成进一步的损害,而修改PYTHONPATH只对从我的用户账户在终端运行的脚本/应用程序有效。
我能否让这些更新的Python版本引用与默认框架安装相同的路径?如果可以,最好的方法是什么?如果不行,有没有公认的方法可以恢复到系统默认设置?
1 个回答
你对Python在OS X上的安装方式有些误解。每个Python实例都有自己的site-packages
目录。标准的安装位置是在框架内的./lib/pythonx.y/site-packages
。所以,对于从python.org下载的安装包,它们会安装到/Library/Frameworks/Python.framework
,你可以在这里找到它的2.6版本的site-packages
:
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/
苹果对它在OS X中提供的Python版本做了一些修改。从OS X 10.5开始,系统自带的Python安装在:
/System/Library/Frameworks/Python.framework
而且苹果选择在每个版本的非标准./Extras
目录中包含一些额外的第三方包。它还使用了一个非标准的位置来存放每个版本的site-packages
目录。这些目录创建在/Library/Python/
,这样做的目的是为了用户安装的包不会修改/System/Library
中的内容。因此,对于苹果提供的Python 2.6,它的site-packages
目录是:
/Library/Python/2.6/site-packages
可以认为它是通过./Extras
中的包进行了扩展。
每个Python实例都有一个独立的site-packages
目录。不同实例之间,即使是同一个小版本的Python(比如2.6),也不应该共享site-packages
中的包,通常也做不到。最明显的问题是,C编译器的版本、OS X的ABI(MACOSX_DEPLOYMENT_TARGET
)、SDK版本和/或用于构建Python解释器的CPU架构可能会有所不同,这些都会影响到Distutils在构建第三方包中的C扩展模块时的表现。
在Mac OS X 10.6中,苹果提供的Python是使用gcc-4.2构建的,专门针对OS X 10.6,并且支持三种CPU架构(i386
、x86_64
和ppc
)。而python.org的Python 2.6安装包则是为了兼容更旧的系统,因此它的目标是10.3及以上,使用gcc-4.0,并且仅支持32位(i386
和ppc
)。所以,通常情况下,你不能在一个Python上运行为另一个Python构建的C扩展模块。
这意味着,通常情况下,如果你需要的第三方包没有随Python一起提供,你需要为每个Python单独安装这些包。这包括像easy_install
(来自setuptools
或Distribute
)这样的基本工具。在10.5及以上的系统自带的Python中,easy_install
的版本位于/usr/bin
。如果你安装了python.org的Python,你需要为它安装一个单独的版本;默认情况下,easy_install
命令会安装在该Python的./bin
目录中,这是Distutils的默认位置。这就是为什么建议你将这个目录添加到你的shell PATH中(而python.org的Python 2安装程序默认会自动这样做)。
Issue4865引入的变化并不是一个好的解决方案,可能会在使用C扩展模块时出现问题。我不建议依赖它在未来的Python版本中继续存在。
另外,安装python.org的Python并不会破坏系统自带的Python,因为它们是完全独立的安装,使用不同的文件系统位置。唯一可能改变的是,当你输入特定名称时,调用的是哪个Python实例。这个主要由你的shell PATH环境变量的搜索顺序控制。如前所述,python.org的安装程序默认会改变这个顺序,但你仍然可以通过使用它的绝对路径/usr/bin/python2.6
来轻松访问系统Python。或者你可以恢复对shell配置文件的更改,比如.bash_profile
。
$ echo $PATH
/Library/Frameworks/Python.framework/Versions/2.6/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
$ which python python2.6
/Library/Frameworks/Python.framework/Versions/2.6/bin/python
/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6
$ python -V
Python 2.6.6
$ python2.6 -V
Python 2.6.6
$ /usr/bin/python -V
Python 2.6.1
$ /usr/bin/python2.6 -V
Python 2.6.1
#
# remove python.org Python 2.6 from PATH
#
$ export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
$ which python python2.6
/usr/bin/python
/usr/bin/python2.6
$ python -V
Python 2.6.1
$ python2.6 -V
Python 2.6.1