我对python很陌生,但对PHP和JavaScript很有经验,对Java相当熟悉(我几乎每天都在使用)。我使用python作为脚本,但到目前为止还没有尝试过一个大型复杂的项目。
我很难理解python处理包导入的方式。我已经搜索和阅读了其他几个答案,但仍然无法让我的具体案例发挥作用。我会想象我的错误是由于糟糕的或非节奏曲的设计,但我觉得我所做的是我工作过的其他语言中的一种常见的做法,所以它应该很简单。
我有以下目录树
+ project (project directory)
+ replicator (source directory)
+ adapters
- __init__.py
- wwf_score.py
- other_adpater.py (there will be many adapter modules in this package)
- sources.py
- __init__.py (empty init for replicator)我正在寻找一个模块化的设计,我可以实例化特定的适配器在动态。这些适配器在abc.ABC中扩展了一个adapters.__init__抽象类,该类还包含一些用于适配器的通用实用程序。
很简单。
问题是,单个适配器模块需要引用replicator.sources中的一些定义。特别是两班。正在发生的情况是,每个适配器从第三方获取数据,并补充一个RawSource对象,该对象是在replicator.sources中定义的。
wwf_score.py
import replicator.adapters as adapters
import replicator.sources as sources
@adapters.source_adapter
class WWFScoreAdapter(adapters.AbstractAdapter):
def __init__(self, data):
self.data = sources.RawData(data)这会引发一个错误,即AttributeError: module 'replicator' has no attribute 'adapters'
我尝试过向replicators.__init__添加一个导入,并尝试过相关导入和其他一些东西。
我做错了什么?
谢谢大家!
编辑
看来,我真正的问题是在一个特定的适配器中从adapters.__init__导入一些东西,或者(不知怎么的)实际将adapters包注册到replicator中。看起来,我可以从replicator.sources内部导入wwf_score.py。也许能帮上忙。
编辑更新,以提高清晰度和可读性。
发布于 2017-07-05 16:45:02
我找到了一个解决方案,但仍然愿意考虑更好的设计
正如我所预料的,我的问题是设计不佳,不了解进口。我试图在一些__init__文件中进行实际的定义,并引用包之外的那些定义。这导致了意大利面代码的出现。最后我做了两件事来解决这个问题:
1.更小、更清晰的模块----我从__init__文件中删除了所有定义,并给出了它们自己的模块。其中之一包括一个装饰器,它是绑定到init文件之外不可用的属性的可调用类。我不知道具体是怎么做的,但我敢肯定这会让事情变得很混乱。
我的新结构看起来像这样(如果有人在乎的话)
+ project
+ bin
- replicator.py (script that uses the rest)
+ replicator
+ adapters
- __init__.py (blank except to import modules)
- contracts.py (pulled from init, includes Abstract)
- registry.py (has a class decorator bound to attribute)
- wwf_score.py (class that extends Abstract)
- other_adapter.py (another class that extends Abstract)
- sources.py (the same, just some dtos)
- __init__.py (empty except for imports)2.我在包中使用了所有相对导入,因此,我的wwf_score.py导入看起来像
from . import contracts
from . import registry
from .. import sources我的bin/replicator.py文件可以通过
import replicator.adapters as adapters
import replicator.sources as sources一切都很好。
我希望这对将来的人有帮助。我可以自由回答关于我的设置和发现的问题。
就像我说的,我的一部分问题是我做了一些其他复杂的事情--一个基于类的装饰师,它装饰了一个类。这被用来将我所有的适配器注册到一个注册表(和一个键),这样我就可以使用工厂来创建它们。
谢谢。
https://stackoverflow.com/questions/44929302
复制相似问题