python - 将包的 __init__.py 模块用于通用抽象类是 pythonic 吗?

标签 python python-3.x abstract-class declaration

我正在按照 python3 中的面向对象模型为我的公司开发一个相当复杂的应用程序。该应用程序包含多个包和子包,每个包和子包当然都包含一个 __init__.py 模块。

我主要使用那些 __init__.py 模块为其中的包声明泛型类,它们仅用作各自包的抽象模板。

我现在的问题是:这是使用 __init__.py 模块的“不错”/“正确”/“pythonic”方式吗?或者我宁愿在其他地方声明我的泛型类?

举个例子,我们假设一个包 mypkg:

mypkg.__init__.py:

class Foo(object):
    __some_attr = None

    def __init__(self, some_attr):
        self.__some_attr = some_attr

    @property
    def some_attr(self):
        return self.__some_attr

    @some_attr.setter
    def some_attr(self, val):
        self.__some_attr = val

mypkg.myfoo.py:

from . import Foo

class MyFoo(Foo):
    def __init__(self):
        super().__init__("this is my implemented value")

    def printme(self):
        print(self.some_attr)

最佳答案

这取决于您要提供的 API 是什么。例如 collections标准库中的模块定义了__init__.py1中的所有类。 标准库应该非常“pythonic”,不管那是什么意思。

但是它主要提供“类似模块”的界面。很少见:

import collections.abc

如果您已经有子包,您最好引入一个新的子包。 如果目前包的使用实际上并不依赖于子包,您可以考虑将代码放在 __init__.py 中。或者将代码放在一些私有(private)模块中,然后简单地在 __init__.py 中导入名称(这是更喜欢的)


如果你只关心抽象基类放在哪里比较好,如上图(collections.abc包含了collections包的抽象基类) ,正如您从标准库的 abc 中看到的那样模块,通常定义一个包含它们的 abc.py 子模块。 您可以考虑直接从 __init__.py 公开它们:

from .abc import *
from . import abc

# ...
__all__ = list_of_names_to_export + abc.__all__

在你的 __init__.py 中。


1 然而,实际使用的实现是在 C 中:_collectionsmodule.c

关于python - 将包的 __init__.py 模块用于通用抽象类是 pythonic 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24266273/

相关文章:

Python子进程模块将路径作为字符串发送

c++ - vector 和抽象类

c# - 为什么我的抽象基类会出现这个编译错误?

python - 从 Linux 连接到 Sun ONC RPC 服务器

python - tensorflow 。如何张量板

python-3.x - 带有 ".all()"的 Flask SQLAlchemy 查询过滤器不返回所有行

android - 如何在java中为抽象函数返回值设置默认值

python - 用于多方面直方图的独立大小的桶

python - 使用 psycopg2 在 python 上进行多进程

python - 安装 PyBrain 时没有名为 'structure' 的模块,即使它在文件夹中