有没有一种方法可以查看Python内置函数的工作原理?我不仅想知道如何使用它们,还想了解它们是如何构建的,sorted或enumerate背后的代码是什么?
有没有一种方法可以查看Python内置函数的工作原理?我不仅想知道如何使用它们,还想了解它们是如何构建的,sorted或enumerate背后的代码是什么?
由于Python是开源的,您可以阅读源代码。
要查找特定模块或函数实现的文件,通常可以打印__file__
属性。或者,您可以使用inspect
模块,参见inspect
文档中的检索源代码部分。
对于内置类和方法来说,这并不那么简单,因为inspect.getfile
和inspect.getsource
将返回类型错误,指出对象是内置的。但是,许多内置类型可以在Python源代码目录下的Objects
子目录中找到。例如,这里是枚举类的实现,这里是list
类型的实现。
以下是补充@Chris的食谱答案,CPython已经转移到GitHub,不再更新Mercurial仓库:
git clone https://github.com/python/cpython.git
代码将检出到名为cpython
的子目录中->cd cpython
print()
的定义...egrep --color=always -R 'print' | less -R
Python/bltinmodule.c
-> builtin_print()
享受吧。
我为了找到以下“内置函数”的来源而花费了一些时间,因为搜索结果会返回成千上万条内容。(祝你好运,要想找到它们的源头)
无论如何,所有这些函数都在bltinmodule.c中定义。函数以builtin_{functionname}开头。
内置源代码:https://github.com/python/cpython/blob/master/Python/bltinmodule.c
对于内置类型:https://github.com/python/cpython/tree/master/Objects
listobject.c
中找到其实现细节 https://github.com/python/cpython/tree/master/Objects - user1767754pow
的实现方式,但只找到了下面这个并没有什么用处的内容:static PyObject * builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, PyObject *mod) { return PyNumber_Power(base, exp, mod); }
。请问有什么简单方法可以找到算法实际实现的位置吗? - Stef两种方法:
help()
查看有关片段用法的信息。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 --
让我们直接来回答你的问题。
如何查找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代码。
Python开发者指南(Developer Guide)是一个相对较为不知名的资源。
在最近的GH问题中,添加了一个新章节来回答你所提出的问题:CPython源代码布局。如果有任何更改,该资源也将得到更新。
如@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
enumerate
的例子吗? - Benjaminsorted()
函数的源代码位于/Python/bltinmodule.c,但实际上它只是调用了list.sort()
,因此真正的源代码位于/Objects/listobject.c。 - user3064538__file__
的例子会更有帮助。 - stackoverflowpro