Different people告诉我,为了提高我的Python编程技能,去看看现有项目是如何实现的会有所帮助。但我在浏览项目并找到我感兴趣的代码部分时有点费劲。
假设我正在使用scipy.signal包的butter,我想知道它是如何实现的,所以我将转到scipy's github repo并移动到signal
文件夹。现在,我应该从哪里开始寻找butter的实现呢?
我也有点搞不清楚什么是模块/包/类/函数。scipy
是模块?还是包?那么signal
是什么?有没有类似module.class.function
的模式?(或者另一个例子:matplotlib.pyplot
...)
1条答案
按热度按时间rdlzhqv91#
听起来你有两个问题。第一,你如何找到
scipy.signal.butter
的实现位置?第二,Python代码的不同层次单元是什么(以及它们与butter
有什么关系)?第一种方法其实有一个简单的解决方案。如果您按照
butter
函数的链接,您会看到一个[source]
链接,就在函数签名的右边。单击它将直接带您到github库中的函数源代码(固定到与您正在阅读的文档版本相匹配的提交,这可能是您所需要的)并非所有API文档都有这种链接,但是当它这样做的时候,它会让事情变得非常容易!至于第二个问题,我不打算详细解释每一个级别,但这里有一些大致的描述,从组织代码的最窄的方式开始,然后移动到更宽的方式。
1.函数是可以从其他代码调用的可重用代码块。函数在运行时有一个本地命名空间。
1.类是将数据与一个或多个函数组织在一起的方法。在类中定义的函数称为方法(但不是所有函数都需要在类中)。类有一个类命名空间,类的每个示例也有自己的示例命名空间。
1.模块是一组代码,通常是函数或方法(但有时也包括数据)。每个模块都有一个全局名称空间。一般来说,每个
.py
文件在加载时都会创建一个模块。一个模块可以通过import
语句访问另一个模块。1.包是一种特殊类型的模块,它由文件夹
foo/
定义,而不是由foo.py
文件定义。这让你可以组织整个模块组,而不是所有模块都在同一层。包可以有更多的子包(用foo/bar/
这样的嵌套文件夹表示)除了可以导入的模块和子包之外,一个包也将有它自己的常规模块命名空间,这将通过运行foo/__init__.py
文件来填充。回到您的问题上来,在您的例子中,
scipy
是一个顶层包,scipy.signal
是其中的一个子包,名称butter
是一个函数,但是它实际上是在scipy/signal/_filter_design.py
文件中定义的。(以及在其模块中定义的所有其他名称)与from ._filter_design import *
(请参阅此处)。在一个内部模块中实现一些东西,然后将其导入到包的
__init__.py
文件中使用,这是一种非常常见的设计。它有助于将过大的模块细分,以方便开发人员,同时仍然有一个单独的地方来访问API的一个大卡盘。然而,这是非常混乱的工作,为自己。因此,如果您自己搞不清楚,也不要感到难过。有时候,您可能需要搜索存储库来找到某个内容的定义,即使您知道从哪里导入它。