对于泛型抽象类,使用包的__init__.py模块是pythonic吗?

Ric*_*ann 10 python abstract-class declaration python-3.x

我正在根据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
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

Bak*_*riu 4

这取决于您想要提供的 API 是什么。例如,标准库中的模块定义了1collections中的所有类。标准库应该非常“Pythonic”,无论这意味着什么。__init__.py

然而,它主要提供了一个“类似模块”的界面。很少见到这样的情况:

import collections.abc
Run Code Online (Sandbox Code Playgroud)

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


如果您只关心最好将抽象基类放在哪里,如上所示(collections.abc包含包的抽象基类collections),并且正如您从标准库的abc模块中看到的那样,通常定义一个abc.py包含它们的子模块。您可以考虑直接从以下行为中暴露它们__init__.py

from .abc import *
from . import abc

# ...
__all__ = list_of_names_to_export + abc.__all__
Run Code Online (Sandbox Code Playgroud)

在你的__init__.py.


1然而,实际使用的是 C 语言:_collectionsmodule.c