导入时省略文件名?

时间:2019-12-03 10:57:38

标签: python

在Python中导入不需要在__init__.py中导入所有内容的类时,有什么方法可以忽略文件名吗?

基本上我现在所拥有的项目结构如下:

project
    ├── __init__.py
    ├── module1
    │   ├── __init__.py
    │   ├── SomeClass.py
    │   └── SomeOtherClass.py
    └── module2
        ├── __init__.py
        └── YetAnotherClass.py

在文件SomeClass.py中,我有一个名为SomeClass的类,依此类推。
我希望能够使用如下的import语句导入这些类:

from project.module1 import SomeClass
from project.module1 import SomeOtherClass

当前,我正在通过module1/__init__.py文件中的这些导入来执行此操作:

from SomeClass import *
from SomeOtherClass import *

问题是SomeOtherClass导入了一个相当大的框架,该框架在导入时启动了一些后台服务,因此,如果我从项目中唯一需要的是SomeClass,我想避免导入它。另外,由于许多其他项目都依赖于此项目,因此我不想更改访问这些类所需的import语句。

我正在寻找一些解决方案,但并没有发现任何有用的方法。
有没有任何重要的重构方法?

1 个答案:

答案 0 :(得分:0)

简短的回答:不,你不能。

在初始导入(第一次在给定过程中导入模块)后,全部执行模块顶层的代码(importdefclass是可执行语句,必须执行才能导入,并创建函数和类对象。

鉴于您所描述的情况,您可以选择:

1 /从其子模块导入SomeClass而不是从软件包中导入{即,将from module1 import SomeClass替换为from module1.SomeClass import SomeClass。至少可以说,这是最简单的解决方法,但它相当脆弱。

2 /从from SomeOtherClass import *中删除__init__,并强制客户端代码显式导入SomeOtherClass子模块。这将破坏客户端代码的兼容性,但至少会更加明确。

3 /修复SomeOtherClass模块,使其不会在后台启动任何服务。 这实际上是唯一的理智的解决方案-导入模块不应该具有启动任何进程之类的副作用。这也将破坏依赖于此反模式的客户端代码,并且现在必须显式启动这些服务,无论它们是什么,但这不需要比解决方案2花费更多的精力,并且至少它将最终解决根源问题。

请注意,可能还有 (或没有...),但是有其他解决方法,但是如果不确切知道SomeOtherClass模块中发生了什么,这是不可能的,这是什么“大框架,该大框架将在导入时启动一些后台服务”,以及该“大框架”是否已经提供了一些更明智的选择来处理启动这些“服务”的方式和时间。

编辑:

  

SomeOtherClass的问题在于,它不会自行启动任何服务,它仅使用一个可以启动服务的框架,而该框架的代码不在我的控制范围之内

我知道不是SomeOtherClass启动了服务,而是其中之一的依赖关系。我的答案主要是试图列出可能的技术解决方案,至少尽可能多地在不了解此框架的情况下,可能比我对xD的实际了解要多得多。

现在,正如我所提到的,即使您没有使用框架,它也可能(或没有)提供一种避免隐式启动这些服务的方法,但是没有人会不知道这个框架是什么。

此外,取决于确切地 SomeOtherClass如何“依赖”此框架,仍然可能存在至少将有问题的部分推迟到某些方法实际需要之前的方法(想到的是代理模式,或者在最坏的情况下是一个猴子补丁)-但是在这里,如果没有手头的真实代码并花一些时间检查它,就无法分辨。

最后,即使您没有使用框架,也可以与框架的维护者讨论该问题。可能是一个失败的原因(如果这是固执的/无关紧要的维护者的专有东西,或者完全损坏以至于他们不得不重写所有内容就无法解决它),但仍然值得尝试,因为它在技术上是最好的解决方案。