使用python

时间:2017-07-05 14:38:35

标签: python adapter python-import circular-dependency

我是python的新手,但对PHP和JavaScript非常熟悉并且非常熟悉Java(我几乎每天都使用它)。我已经将python用于脚本,但直到现在才尝试过大型的复杂项目。

我很难绕过python处理包导入的方式。我有搜索和阅读其他几个答案,但仍然无法让我的具体案例工作。我想我的错误是由于坏的或非pythonic设计,但我觉得我正在做的是在我使用的其他语言中这种常见的做法,它应该很简单。

我有以下目录树

+ 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.sourceswwf_score.py导入,它出现了。也许这有帮助。

编辑为了清晰度和可读性而进行了更新。

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案,但对于更好的设计仍然存在想法

正如我所料,我的问题是设计不佳而不了解进口。我试图在一些__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

一切都很好。

我希望这有助于将来的某些人。我可以自由回答有关我的设置和我发现的问题。

就像我说的,我的一部分问题是我正在做一些复杂的事情 - 一个基于类的装饰器来装饰一个类。这用于将所有个人适配器注册到注册表(和密钥),因此我可以使用工厂来创建它们。

感谢。