寻找内置Python函数的源代码?

232

有没有一种方法可以查看Python内置函数的工作原理?我不仅想知道如何使用它们,还想了解它们是如何构建的,sortedenumerate背后的代码是什么?

8个回答

215

由于Python是开源的,您可以阅读源代码

要查找特定模块或函数实现的文件,通常可以打印__file__属性。或者,您可以使用inspect模块,参见inspect文档中的检索源代码部分。

对于内置类和方法来说,这并不那么简单,因为inspect.getfileinspect.getsource将返回类型错误,指出对象是内置的。但是,许多内置类型可以在Python源代码目录下的Objects子目录中找到。例如,这里是枚举类的实现,这里是list类型的实现


你能举一个使用 enumerate 的例子吗? - Benjamin
4
sorted()函数的源代码位于/Python/bltinmodule.c,但实际上它只是调用了list.sort(),因此真正的源代码位于/Objects/listobject.c - user3064538
3
如果你举了一个使用__file__的例子会更有帮助。 - stackoverflowpro
5
作为自己的备忘录,以及未来的谷歌搜索者:在Python 3中,“open()”函数定义在“Modules/_io/_iomodule.c”中(而不是其他内置函数中)。 - peter.slizik
1
我尝试使用input.__file__,但它显示“builtin_function_or_method”对象没有属性“__file__”。:-\ - Jitin
显示剩余2条评论

49

以下是补充@Chris的食谱答案,CPython已经转移到GitHub,不再更新Mercurial仓库:

  1. 如果有必要,请安装Git。
  2. git clone https://github.com/python/cpython.git

  3. 代码将检出到名为cpython的子目录中->cd cpython

  4. 假设我们正在寻找print()的定义...
  5. egrep --color=always -R 'print' | less -R
  6. 啊哈!请查看Python/bltinmodule.c -> builtin_print()

享受吧。


7
bltinmodule。啊啊啊啊啊,他们为什么要拼错它的拼写?我尝试了一下快速的文件系统搜索builtin,但是没有找到任何东西! - Pod

44

1
列表是一个对象/类型,而不是内置函数。您可以在listobject.c中找到其实现细节 https://github.com/python/cpython/tree/master/Objects - user1767754
“dir”在C中没有实现,因此它不在那个文件中。 - user3064538
寻找Python内置模块bltinmodule.c中builtin pow的实现方式,但只找到了下面这个并没有什么用处的内容:static PyObject * builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, PyObject *mod) { return PyNumber_Power(base, exp, mod); }。请问有什么简单方法可以找到算法实际实现的位置吗? - Stef

26

iPython shell可以轻松实现这一点:function?将为您提供文档。 function??也显示代码。但是,这仅适用于纯Python函数。

然后,您始终可以download (c)Python的源代码。

如果您对核心功能的Pythonic实现感兴趣,请查看PyPy源代码。


1
PyPy使用RPython来实现大部分内置功能,其级别可以接近于C语言的底层,也可以接近于Python语言的高层。通常情况下,它们处于中间水平。无论哪种情况,它都是静态类型的,因此它并不是真正的Python语言。 - user395760
2
查看内置函数源代码的早期项目:https://github.com/punchagan/cinspect - Thomas

16

两种方法:

  1. 您可以使用 help() 查看有关片段用法的信息。
  2. 您可以使用 inspect 检查这些模块的隐藏代码。

1)inspect:

使用 inspect 模块来探索您想要的代码...注意:您只能探索您导入的模块(也称为软件包)的代码。

例如:

  >>> import randint  
  >>> from inspect import getsource
  >>> getsource(randint) # here i am going to explore code for package called `randint`

2) help():

你可以使用help()命令来获取内置函数及其代码的帮助。

例如:如果您想查看str()的代码,只需输入 - help(str)

它将返回以下内容:

>>> help(str)
Help on class str in module __builtin__:

class str(basestring)
 |  str(object='') -> string
 |
 |  Return a nice string representation of the object.
 |  If the argument is a string, the return value is the same object.
 |
 |  Method resolution order:
 |      str
 |      basestring
 |      object
 |
 |  Methods defined here:
 |
 |  __add__(...)
 |      x.__add__(y) <==> x+y
 |
 |  __contains__(...)
 |      x.__contains__(y) <==> y in x
 |
 |  __eq__(...)
 |      x.__eq__(y) <==> x==y
 |
 |  __format__(...)
 |      S.__format__(format_spec) -> string
 |
 |      Return a formatted version of S as described by format_spec.
 |
 |  __ge__(...)
 |      x.__ge__(y) <==> x>=y
 |
 |  __getattribute__(...)
-- More  --

10
OP特别想查看代码,帮助只提供文档。 - 0xc0de

11

让我们直接来回答你的问题。

如何查找Python内置函数的源代码?

源代码位于cpython/Python/bltinmodule.c

要在GitHub存储库中查找源代码,请单击此处。你可以看到所有内置函数都以builtin_<name_of_function>开头,例如sorted()builtin_sorted中实现。

以下是sorted()实现,以供参考:

builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
    PyObject *newlist, *v, *seq, *callable;

    /* Keyword arguments are passed through list.sort() which will check
       them. */
    if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq))
        return NULL;

    newlist = PySequence_List(seq);
    if (newlist == NULL)
        return NULL;

    callable = _PyObject_GetAttrId(newlist, &PyId_sort);
    if (callable == NULL) {
        Py_DECREF(newlist);
        return NULL;
    }

    assert(nargs >= 1);
    v = _PyObject_FastCallKeywords(callable, args + 1, nargs - 1, kwnames);
    Py_DECREF(callable);
    if (v == NULL) {
        Py_DECREF(newlist);
        return NULL;
    }
    Py_DECREF(v);
    return newlist;
}

你可能已经注意到了,那不是Python代码,而是C代码。


10

Python开发者指南(Developer Guide)是一个相对较为不知名的资源。

在最近的GH问题中,添加了一个新章节来回答你所提出的问题:CPython源代码布局。如果有任何更改,该资源也将得到更新。


8

如@Jim所述,文件组织方式在这里有描述。为方便查找,再次呈现:

For Python modules, the typical layout is:

Lib/<module>.py
Modules/_<module>.c (if there’s also a C accelerator module)
Lib/test/test_<module>.py
Doc/library/<module>.rst

For extension-only modules, the typical layout is:

Modules/<module>module.c
Lib/test/test_<module>.py
Doc/library/<module>.rst

For builtin types, the typical layout is:

Objects/<builtin>object.c
Lib/test/test_<builtin>.py
Doc/library/stdtypes.rst

For builtin functions, the typical layout is:

Python/bltinmodule.c
Lib/test/test_builtin.py
Doc/library/functions.rst

Some exceptions:

builtin type int is at Objects/longobject.c
builtin type str is at Objects/unicodeobject.c
builtin module sys is at Python/sysmodule.c
builtin module marshal is at Python/marshal.c
Windows-only module winreg is at PC/winreg.c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接