Pythonic的模块和包组织方式

50

我一般按类创建一个文件,并将常见类组织到目录下。在C++、PHP、JavaScript等语言中,这种做法对我来说很直观,而且已经被证明是有效的。

但是,我在将这个方法带入Python时遇到了麻烦:文件不再只是文件,而是形式化模块。仅仅在一个模块中拥有一个类似乎并不合适——大多数类本身都是无用的。如果我有一个叫做automobile.py的模块和一个名为Automobile的类,总是将其称为automobile.Automobile似乎很愚蠢。

但是,同时,把大量代码扔进一个文件里就结束了也不对。显然,非常复杂的应用程序应该有多于5个文件。

那么正确的——或者符合Python风格的——方法是什么?(如果没有正确的方法,你有什么首选方法以及原因?)我应该在Python模块中放多少代码?


请勿重复:https://dev59.com/53I-5IYBdhLWcg3w18Z3 - S.Lott
1
重复:https://dev59.com/33VD5IYBdhLWcg3wDHDm - S.Lott
《C++ 核心准则》实际上不建议将每个类的声明放在单独的源文件中,这种做法不被推荐。 - 303
5个回答

39

考虑到“逻辑封装单元”,这可能是一个单一的类,但更常见的情况是一组密切协作的类。根据这个标准,可以将类(或模块级别函数 - 不要通过始终使用静态方法来在Python中进行Java编程!)进行分组。如果大多数A的用户也需要B,反之亦然,则A和B应该位于同一模块中;但是,如果许多用户只需要其中一个而不需要另一个,则它们应该位于不同的模块中(可能在同一个包中,即带有__init__.py文件的目录中)。

标准的Python库虽然远非完美,但往往反映了合理的实践 - 因此,您可以通过示例来学习。例如,threading模块当然定义了一个Thread类...但它还包括锁、事件、条件和信号量等同步原语类,以及可以被线程操作引发的异常类(和一些其他内容)。它处于合理大小的上限(包括空格和文档字符串在内的800行),一些关键的与线程相关的功能(如队列)已被置于单独的模块中,但它是将最大数量的功能打包到单个模块中仍然有意义的好示例。


11

如果您想坚持每个文件一个类的系统(这是合理的,不要误解我的意思),您可以像这样做,以避免不得不引用automobile.Automobile

from automobile import Automobile
car = Automobile()

然而,正如cobbal所提到的,Python中一个文件包含多个类是非常常见的。无论哪种方式,只要选择一个合理的系统并保持一致使用,我认为没有Python用户会对此有所不满 :)


7

如果你从c++的角度来看,你可以把python模块视为.so或.dll文件。是的,它们看起来像源代码文件,因为python是脚本语言,但实际上它们是具有特定功能的可加载库。

另一个可能有帮助的比喻是你可以把python模块看作命名空间。


4
在一个中等规模的项目中,我发现自己有几组密切相关的类。其中几个集合现在已经分组到文件中;例如,低级网络类都在单独的“network”模块中。然而,一些最大的类已经被拆分成它们自己的文件。
也许从一个每个文件一个类的历史开始走向这条路的最好方法是将通常放置在同一目录下的类保存在同一个文件中。如果该文件开始看起来太大,请将其拆分。

3

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