我正在按照 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__.py
1中的所有类。
标准库应该非常“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/