Pythonic的模块和包组织方式

50 投票
5 回答
26199 浏览
提问于 2025-04-15 16:24

我之前的编程习惯是每个类都放在一个文件里,还会把一些常用的类放在不同的文件夹里。这种做法对我来说很自然,而且在C++、PHP、JavaScript等语言中也很有效。

现在我在用Python时遇到了一些困惑:在Python中,文件不仅仅是文件,它们还是正式的模块。一个模块里只放一个类似乎不太对,因为大多数类单独存在是没什么用的。如果我有一个叫automobile.py的文件,里面有一个Automobile类,那每次引用的时候都要写成automobile.Automobile,这听起来有点傻。

但与此同时,把很多代码都放在一个文件里也不太合适。显然,一个复杂的应用程序应该有超过5个文件。

那么,正确的做法是什么呢?或者说,Python中比较合适的做法是什么?如果没有绝对正确的方式,你更喜欢哪种方式,为什么?在一个Python模块里应该放多少代码比较合适呢?

5 个回答

7

如果你是从C++的角度来看,Python的模块可以看作是类似于.so或.dll的东西。虽然它们看起来像源文件,因为Python是脚本语言,但实际上它们是可以加载的特定功能库。

另一个可以帮助理解的比喻是,你可以把Python模块看作是命名空间。

11

如果你想坚持每个文件只放一个类(这个想法是合理的,别误会我),你可以像这样做,以避免每次都要写 automobile.Automobile

from automobile import Automobile
car = Automobile()

不过,正如cobbal提到的,在Python中一个文件放多个类是很常见的。无论你选择哪种方式,只要你选一个合理的系统并且始终如一地使用它,我觉得没有哪个Python用户会对你生气的 :).

39

想象一下“逻辑包装单元”这个概念——这可能是一个单独的类,但更常见的是一组紧密合作的类。类(或者模块级别的函数——不要在Python中用静态方法来“做Java”,因为模块级别的函数也是一个选择!)可以根据这个标准进行分组。简单来说,如果大多数使用A的人也需要B,反之亦然,那么A和B应该放在同一个模块里;但如果很多人只需要其中一个而不需要另一个,那它们就应该放在不同的模块里(也许在同一个包里,也就是有一个__init__.py文件的目录)。

标准的Python库虽然不是完美的,但大体上反映了比较好的实践——所以你可以通过它的例子来学习。例如,threading模块当然定义了一个Thread类……但它还包含了一些同步原语类,比如锁、事件、条件和信号量,还有一个可以在线程操作中引发的异常类(以及其他一些东西)。这个模块的大小在合理范围的上限(包括空白和文档字符串在内有800行),而一些关键的与线程相关的功能,比如队列(Queue),被放在了一个单独的模块里,尽管如此,它仍然是一个很好的例子,展示了在一个模块中打包多少功能是合理的。

撰写回答