不同的人告诉我,为了改善我的Python编程技能,有助于去看看现有项目的实施方式。但是我正在努力浏览项目并找到我感兴趣的代码部分。
假设我正在使用 scipy.signal包的butter ,我想知道它是如何实现的,所以我要 scipy的github repo ,然后移至 signal
文件夹。现在,我应该从哪里开始寻找黄油的实施?
我对模块/软件包/类/函数是什么感到有些困惑。 Scipy
一个模块吗?还是包裹?那么什么是信号
?是否有某种模式,例如 module.class.function
? (或另一个示例: matplotlib.pyplot
...)
Different people have told me that in order to improve my Python programming skills, it helps to go and look how existing projects are implemented. But I am struggeling a bit to navigate through the projects and find the parts of the code I'm interested in.
Let's say I'm using butter of the scipy.signal package, and I want to know how it is implemented, so I'm going to scipy's github repo and move to the signal
folder. Now, where is the first place I should start looking for the implementation of butter?
I am also a bit confused about what a module/package/class/function is. Is scipy
a module? Or a package? And then what is signal
? Is there some kind of pattern like module.class.function
? (Or another example: matplotlib.pyplot
...)
发布评论
评论(1)
听起来您在这里有两个问题。首先,您如何找到
scipy.signal.butter
实现的位置?其次,Python代码的不同层次单元是什么(它们与该Butter
Thits有何关系)?第一个实际上有一个简单的解决方案。如果您遵循
Butt
函数给出的链接,则将看到[source]
链接在功能签名的右侧。单击这将带您(固定在与您正在阅读的文档的版本相匹配的提交中,这可能是您想要的)。并非所有的API文档都会具有这种链接,但是当它这样做时,它确实使事情变得非常容易!至于第二个问题,我不会完全解释每个级别,但是这里有一些广泛的笔触,从组织代码的最狭窄方式开始,然后转向更广泛的方式。
函数是可重复使用的代码块,您可以从其他代码调用。功能在运行时具有本地名称空间。
类是组织数据以及一个或多个功能的方式。在类中定义的功能称为方法(但并非所有功能都必须在类中)。类具有类名称空间,并且类的每个实例都有其自己的实例名称空间。
模块是代码组的组,通常是功能或方法(但有时也有其他内容,例如数据)。每个模块都有一个全局名称空间。一般而言,每个
.py
文件将在加载时创建一个模块。一个模块可以使用import
语句。访问另一个模块。
软件包是一种特殊的模块,由文件夹
foo/
定义,而不是foo.py
文件。这使您可以组织整个模块,而不是所有级别的模块。软件包可以具有进一步的子包装(用foo/bar/
等嵌套文件夹表示。除了可以导入的模块和子包外,软件包还将具有自己的常规模块名称空间,该空间将通过运行foo/__ Init __. py
file。为了将其重新回到您的特定问题,在您的情况下,
scipy
是顶级软件包,scipy.signal
是其中的子包装。名称黄油
是一个函数,但实际上是在scipy/signal/_filter_design.py.py
文件中定义的。您可以从scipy.signal
直接访问它,因为scipy/signal/__ init __. py
带有的所有其他名称(以及来自其模块中定义的所有其他名称)。 _filter_design导入 *
(请参阅)。在内部模块中实现某些内容,然后将其导入到软件包的
__ INT __。py
文件中的设计是一个很常见的文件。它有助于将太大的模块细分,以便于他们的开发人员,同时仍然有一个地方访问API的大量chuck。但是,为自己锻炼很困惑,所以如果您自己无法弄清楚,那就不会感到难过。有时,即使您知道自己从何处导入,您可能需要搜索存储库来找到某物的定义。It sounds like you have two questions here. First, how do you find where
scipy.signal.butter
is implemented? Second, what are the different hierarchical units of Python code (and how do they relate to thatbutter
thing)?The first one actually has an easy solution. If you follow the link you gave for the
butter
function, you will see a[source]
link just to the right of the function signature. Clicking on that will take you directly to the source of the function in the github repository (pinned to the commit that matches the version of the docs you were reading, which is probably what you want). Not all API documentation will have that kind of link, but when it does it makes things really easy!As for the second question, I'm not going to fully explain each level, but here are some broad strokes, starting with the most narrow way of organizing code and moving to the more broad ways.
Functions are reusable chunks of code that you can call from other code. Functions have a local namespace when they are running.
Classes are ways of organizing data together with one or more functions. Functions defined in classes are called methods (but not all functions need to be in a class). Classes have a class namespace, and each instance of a class also has its own instance namespace.
Modules are groups of code, often functions or methods (but sometimes other stuff like data too). Each module has a global namespace. Generally speaking, each
.py
file will create a module when it is loaded. One module can access another module by using animport
statement.Packages are a special kind of module that's defined by a folder
foo/
, rather than afoo.py
file. This lets you organize whole groups of modules, rather than everything being at the same level. Packages can have further sub-packages (represented with nested folders likefoo/bar/
). In addition to the modules and subpackages that can be imported, a package will also have its own regular module namespace, which will be populated by running thefoo/__init__.py
file.To bring this back around to your specific question, in your case,
scipy
is a top-level package, andscipy.signal
is a sub-package within it. The namebutter
is a function, but it's actually defined in thescipy/signal/_filter_design.py
file. You can access it directly fromscipy.signal
becausescipy/signal/__init__.py
imports it (and all the other names defined in its module) withfrom ._filter_design import *
(see here).The design of implementing something in an inner module and then importing it for use in the package's
__init__.py
file is a pretty common one. It helps modules that would be excessively large to be subdivided, for ease of their developers, while still having a single place to access a big chuck of the API. It is, however, very confusing to work out for yourself, so don't feel bad if you couldn't figure it out yourself. Sometimes you may need to search the repository to find the definition of something, even if you know where you're importing it from.