在模块和/或包中组织 Python 类

Posted

技术标签:

【中文标题】在模块和/或包中组织 Python 类【英文标题】:Organizing Python classes in modules and/or packages 【发布时间】:2011-04-20 01:09:09 【问题描述】:

我喜欢每个文件有一个公共类的 Java 约定,即使有时有充分的理由将多个公共类放入一个文件中。就我而言,我有相同接口的替代实现。但如果我将它们放入单独的文件中,我会在导入语句中使用冗余名称(或误导性模块名称):

import someConverter.SomeConverter

someConverter 是文件(和模块)名,SomeConverter 是类名。这对我来说看起来很不雅。将所有替代类放在一个文件中会导致更有意义的导入语句:

import converters.SomeConverter

但是我担心如果我将所有相关的类放到一个单独的模块文件中,文件会变得非常大。这里的 Python 最佳实践是什么?每个文件一个类是否不寻常?

【问题讨论】:

当您处理一个由 10,000 个类组成的项目时,如果您可以通过文件(和包)名称找到(公共)类而不是拥有搜索所有文件的内容。这可能是 Java 强制每个文件只有一个公共类并且文件名必须是类名的原因。 【参考方案1】:

很多都是个人喜好。使用 python 模块,您可以选择将每个类保存在单独的文件中,并且仍然允许import converters.SomeConverter(或from converters import SomeConverter

您的文件结构可能如下所示:

* converters
     - __init__.py
     - baseconverter.py
     - someconverter.py
     - otherconverter.py

然后在您的__init__.py 文件中:

from baseconverter import BaseConverter
from otherconverter import OtherConverter

【讨论】:

【参考方案2】:

Zach 的解决方案在 Python 3 上中断。这是一个固定的解决方案。

很多都是个人喜好。使用 python 模块,您可以选择将每个类保存在一个单独的文件中,并且仍然允许import converters.SomeConverter(或from converters import SomeConverter

您的文件结构可能如下所示:

* converters
     - __init__.py
     - baseconverter.py
     - someconverter.py
     - otherconverter.py

然后在您的__init__.py 文件中:

from converters.baseconverter import BaseConverter
from converters.otherconverter import OtherConverter

【讨论】:

“从 .baseconverter 导入 BaseConverter”怎么样? 抱歉,后续跟进晚了,我最近与 python 脱节,如果有人可以验证 Michael 的上述解决方案,请随时编辑我的答案并将其添加为替代方案。 (不要更改我的原件,因为我认为哪个看起来更具可读性是一个偏好问题,所以让我们给用户两个选项) Michael 的回答确实有效,但 PEP 8 不鼓励相对导入。 ***.com/questions/4209641/… @JasonPearson 不再是,显式相对导入适用于包内导入:mail.python.org/pipermail/python-dev/2010-October/104476.html【参考方案3】:

上面的解决方案都不错,但是在__init__.py中导入模块的问题是这会导致所有的模块都被加载两次(效率低下)。尝试在otherconverter.py 的末尾添加打印语句并运行otherconverter.py。 (你会看到 print 语句被执行了两次)

我更喜欢以下内容。使用另一个名为“_converter”的包并在那里定义所有内容。然后你的“converters.py”就变成了访问所有公共成员的接口

* _converters
     - __init__.py
     - baseconverter.py
     - someconverter.py
     - otherconverter.py

*  converters.py

converters.py 在哪里

from _converters.someconverter import SomeConverter
from _converters.otherconverter import OtherConverter
...
...
...
converters = [SomeConverter, OtherConverter, ...]

正如前面提到的解决方案,这是个人选择。一些实践涉及在包中定义一个模块“interace.py”并在此处导入所有公共成员。如果你有很多模块要加载,你应该选择效率而不是美观。

【讨论】:

以上是关于在模块和/或包中组织 Python 类的主要内容,如果未能解决你的问题,请参考以下文章

Python导入模块问题

在包中运行模块没有模块错误[重复]

Python:“导入”更喜欢啥 - 模块或包?

Python3中的模块

python中动态导入模块

浅谈python中得import xxx,from xxx import xxx, from xxx import *