__init__.py导入默认类

时间:2019-04-06 22:58:30

标签: python

假设我在各自的.py文件中分别拥有ClassA,ClassB和ClassC,这些文件分别称为ClassA.pyClassB.pyClassC.py

# Inside ClassA.py
class ClassA:
    pass

在我的__init__.py中,我最终以

from .ClassA import ClassA
from .ClassB import ClassB
from .ClassC import ClassC

每次添加一个新类(使用相同的结构)时,都必须更改__init__.py。鉴于此包中的所有文件都遵循相同的结构(不是相当的pythonic-but-oh-well),有没有建议的自动化方法?

2 个答案:

答案 0 :(得分:2)

这是可能,但不推荐。

请考虑以下目录结构:

├── test_module
│   ├── ClassA.py
│   ├── ClassB.py
│   └── __init__.py

我们希望以编程方式将ClassA.ClassAClassB.ClassB导入__init__.py

假设这些是ClassA.py的内容:

class ClassA:
    pass

ClassB.py是相同的,除了class的名称。

现在,假设在__init__.py中,我们想以非递归方式遍历根目录(由于没有目录,所以没关系),并从其中的所有模块导入所有classes

>

__init__.py

import os
from importlib import import_module

my_location = os.path.dirname(__file__)
module_list = [file
               for file in os.listdir(my_location)
               if os.path.splitext(file)[1] == '.py'
               and file != '__init__.py']
modules = [import_module(f'.{os.path.splitext(module)[0]}', __name__)
           for module in module_list]

运行import test_module之后,来自classesClassA.py的{​​{1}}将分别以ClassB.pytest_module.ClassA.ClassA的形式导入工作名称空间。

说明:

test_module.ClassB.ClassB

出于完整性考虑,如果您希望此脚本模仿>>> import test_module >>> test_module.ClassA.ClassA() <test_module.ClassA.ClassA object at 0x7f1e66181fd0> 的行为:

from X import Y

导入:

globals().update({name: getattr(module, name)
                  for module in modules
                  for name in module.__dict__
                  if not name.startswith('_')})

这些将使这些名称可以用>>> import test_module >>> test_module.ClassA() <test_module.ClassA.ClassA object at 0x7fb8edb9dfd0> 等访问(因为您是从 test_module.ClassA导入的,所以我们添加了一个间接层。在test_module中的范围,可以直接使用无限定名称来访问它们。

我们还可以添加其他功能,例如检查每个模块的test_module属性并执行子目录的递归遍历,但这超出了这个问题的范围,我必须强调我的想法是,最好重构您的代码,这样一来就不需要,而不是强加于似乎不太强大的Python内部功能>必不可少。

答案 1 :(得分:1)

是的,可以。这就是importlib包的用途。它包含实际执行导入的较低级别的调用。它使您可以通过调用提供的方法来进行导入。

因此,您可以使用Python os.path.listdir或其他方法来学习子包,然后调用importlib来导入每个子包。

我本人并没有做太多事情。足以知道这个存在。也许其他人可以给您更多细节。另外,此链接可能对您有所帮助:

https://dev.to/0xcrypto/dynamic-importing-stuff-in-python--1805