我现在确实有些头疼,试图找出如何正确导入东西的方法。我的应用程序结构如下:
main.py
util_functions.py
widgets/
- __init__.py
- chooser.py
- controller.py
我将始终从根目录运行我的应用程序,因此我的大多数导入操作都是这样的
from util_functions import *
from widgets.chooser import *
from widgets.controller import *
# ...
我的widgets/__init__.py
设置是这样的:
from widgets.chooser import Chooser
from widgets.controller import MainPanel, Switch, Lever
__all__ = [
'Chooser', 'MainPanel', 'Switch', 'Lever',
]
一切正常,除了widgets/controller.py
变得很冗长,我希望将它分割成多个文件:
main.py
util_functions.py
widgets/
- __init__.py
- chooser.py
- controller/
- __init__.py
- mainpanel.py
- switch.py
- lever.py
问题之一是Switch
andLever
类具有静态成员,每个类都需要访问其他成员。将导入与from ___ import ___
创建循环导入的语法一起使用。因此,当我尝试运行重构的应用程序时,一切都在导入时中断了。
我的问题是:如何修复导入,以便拥有良好的项目结构?我无法删除的静态依赖Switch
和Lever
互相。
官方的Python常见问题解答中涵盖了这一点,我如何拥有相互导入的模块。
正如常见问题解答所表明的那样,没有神奇的方法可以解决问题。常见问题解答中描述的选项(比常见问题解答中的详细信息更多):
from spam import
东西,然后通常不会出现循环导入问题。简洁明了,但在某些情况下您可能无法遵循这些规则。如常见问题解答所述,“这些解决方案不是互斥的。” 特别是,您可以尝试将尽可能多的顶级代码移入函数主体,用合理的替换尽可能多的from spam import …
语句import spam
……然后,如果您仍然有循环依赖项,请通过重构为上述无导入导出代码来解决它们生产线或单独的模块中。
不用考虑一般性,让我们看看您的特定问题。
您的switch.Switch
和lever.Lever
类具有“静态成员,每个类都需要访问其他成员”。我假设您是说它们具有使用其他类的类属性或类或静态方法初始化的类属性?
在第一个解决方案之后,您可以进行更改,以便在导入时间后初始化这些值。假设您的代码如下所示:
class Lever:
switch_stuff = Switch.do_stuff()
# ...
您可以将其更改为:
class Lever:
@classmethod
def init_class(cls):
cls.switch_stuff = Switch.do_stuff()
现在,在之后的__init__.py
,:
from lever import Lever
from switch import Switch
…您添加:
Lever.init_class()
Switch.init_class()
这就是诀窍:通过使初始化显式并选择一个显式顺序来解决模棱两可的初始化顺序。
或者,按照第二个或第三个解决方案,您可以将Lever拆分为Lever
和LeverImpl
。然后你做到这一点(无论是作为独立的lever.py
和leverimpl.py
文件,或作为一个文件在中间进口):
class Lever:
@classmethod
def get_switch_stuff(cls):
return cls.switch_stuff
from switch import Swift
class LeverImpl(Lever):
switch_stuff = Switch.do_stuff()
现在,您不需要任何init_class
方法。当然,您确实需要将属性更改为方法,但是,如果您不喜欢这样做,则可以通过一些工作将其更改为“类@property
”(通过编写自定义描述符或使用@property
in元类)。
请注意,您实际上不需要修复两个类来解决循环问题,只需修复一个即可。从理论上讲,修复这两种方法比较干净,但是在实践中,如果修复起来很丑陋,则只修复不那么丑陋的修复程序,而将依赖项放在相反的方向可能会更好。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句