如何找到Python模块源的位置?

How do I find the location of Python module sources?

如何了解给定python模块的源文件安装位置?在Windows上的方法与在Linux上的方法不同吗?

我正在特别寻找datetime模块的来源,但我也对更一般的答案感兴趣。


对于纯python模块,您可以通过查看themodule.__file__找到源代码。然而,datetime模块是用C编写的,因此datetime.__file__指向一个.so文件(Windows上没有datetime.__file__文件),因此您看不到源文件。

如果您下载了一个python源tarball并将其提取出来,那么可以在modules子目录中找到模块的代码。

例如,如果要查找python 2.6的日期时间代码,可以查看

1
Python-2.6/Modules/datetimemodule.c

您还可以在网站上找到最新的Mercurial版本:https://hg.python.org/cpython/file/tip/modules/datetimemodule.c


从命令行运行python -v应该可以告诉您导入了什么以及从何处导入。这在Windows和Mac OS X上都适用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
C:\>python -v
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# C:\Python24\lib\site.pyc has bad mtime
import site # from C:\Python24\lib\site.py
# wrote C:\Python24\lib\site.pyc
# C:\Python24\lib\os.pyc has bad mtime
import os # from C:\Python24\lib\os.py
# wrote C:\Python24\lib\os.pyc
import nt # builtin
# C:\Python24\lib
tpath.pyc has bad mtime
...

我不知道我安装了什么坏的mtime!


我意识到这个答案晚了4年,但现有的答案误导了人们。

正确的方法是永远不要使用__file__,也不要试图穿过sys.path,寻找自己,等等(除非你需要向后兼容超过2.1)。

它是inspect模块,特别是getfilegetsourcefile模块。

除非您想学习和执行规则(这些规则对于cpython 2.x是有文档记录的,但很痛苦,对于其他实现则完全没有文档记录,或者对于将.pyc映射到.py文件是3.x);处理.zip文件、eggs和模块包;尝试不同的方法获取到.so.pyd文件的路径不支持__file__;弄清楚jython/ironpython/pypy是做什么的;在这种情况下,就去做吧。

同时,2.0+版本的每个python版本的源代码都可以在线访问http://hg.python.org/cpython/file/X.Y/(例如2.7或3.3)。因此,一旦发现inspect.getfile(datetime).so.pyd文件,如/usr/local/lib/python2.7/lib-dynload/datetime.so文件,就可以在modules目录中查找它。严格来说,没有办法确定哪个文件定义了哪个模块,但几乎所有的模块都是foo.cfoomodule.c,所以不难猜测datetimemodule.c是您想要的。


sys.path列表包含将在运行时搜索模块的目录列表:

1
2
3
4
python -v
>>> import sys
>>> sys.path
['', '/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', ... ]


如果您使用PIP安装模块,只需返回pip show $module位置。


从标准库中尝试imp.find_模块

1
2
3
4
5
>>> import imp
>>> imp.find_module('fontTools')
(None, 'C:\\Python27\\lib\\site-packages\\FontTools\\fontTools', ('', '', 5))
>>> imp.find_module('datetime')
(None, 'datetime', ('', '', 6))


datetime是一个内置模块,因此没有(python)源文件。

对于来自.py.pyc文件的模块,可以使用mymodule.__file__,例如:

1
2
3
4
> import random
> random.__file__
'C:\\Python25\\lib\
andom.pyc'

在python解释器中,您可以导入特定的模块,然后键入帮助(module)。这提供了诸如名称、文件、模块文档、描述等详细信息。

前任:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import os

help(os)


Help on module os:

NAME

os - OS routines for Mac, NT, or Posix depending on what system we're on.

FILE

/usr/lib/python2.6/os.py

MODULE DOCS

http://docs.python.org/library/os

DESCRIPTION

This exports:

- all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.

- os.path is one of the modules posixpath, or ntpath

- os.name is '
posix', 'nt', 'os2', 'ce' or 'riscos'


在python 3.2中,您现在可以使用dis模块中的code_info():http://docs.python.org/dev/whatsnew/3.2.html_dis


下面是一个一行程序,用于获取适用于外壳别名的模块的文件名:

1
echo 'import sys; t=__import__(sys.argv[1],fromlist=["."]); print(t.__file__)'  | python -

设置为别名:

1
alias getpmpath="echo 'import sys; t=__import__(sys.argv[1],fromlist=["."]); print(t.__file__)'  | python -"

使用方法:

1
2
3
4
$ getpmpath twisted
/usr/lib64/python2.6/site-packages/twisted/__init__.pyc
$ getpmpath twisted.web
/usr/lib64/python2.6/site-packages/twisted/web/__init__.pyc


在包含指定python模块源的目录中,查看这个漂亮的"cdp"命令cd:

1
2
3
4
5
cdp () {
  cd"$(python -c"import os.path as _, ${1}; \
    print _.dirname(_.realpath(${1}.__file__[:-1]))"
  )"

}


在Windows上,您可以找到python模块的位置,如下所示:即find rest_framework模块enter image description here


在Ubuntu 12.04上,例如用于python2的numpy包,可以在以下位置找到:

1
/usr/lib/python2.7/dist-packages/numpy

当然,这不是一般的答案


对于那些喜欢使用GUI解决方案的人:如果您使用的是诸如Spyder(水蟒安装的一部分)之类的GUI,您可以右键单击模块名(如"导入csv"中的"csv"),然后选择"转到定义"-这将打开文件,但在顶部也可以看到确切的文件位置("c:….csv.py")。


并非所有的python模块都是用python编写的。datetime恰好是其中之一,而(在Linux上)是datetime.so。

您必须将源代码下载到Python标准库中才能得到它。