结构导入错误:"fab task" vs. "from fabfile import task; task()"



这也与Python的导入机制有关,特别是与在函数中使用import有关。使用Python 2.7.9和Fabric 1.10.0,创建以下三个文件:

fabfile.py:

from another import another_hello
def hello():
print 'hello, world'
another_hello()

another.py:

def another_hello():
from secret import TEXT
print 'Hello, world!'
print 'text: ' + TEXT

secret/__init__.py:(同时创建文件夹secret/)

TEXT = 'secret'

现在试试fab hello。它抱怨道:

File "/home/sergey/projects/Bask/service/t/fabfile.py", line 4, in hello
another_hello()
File "/home/sergey/projects/Bask/service/t/another.py", line 2, in another_hello
from secret import TEXT
ImportError: No module named secret

同时,您可以轻松启动解释器并键入from fab import hello; hello()。完美工作:

In [2]: from fabfile import hello; hello() 
hello, world
Hello, world!
text: secret

为什么会有这种差异?

现在,我找到了一个破解方法,使这个工作。只需在fabfile.py的开头添加一个import secret即可。我认为fab工具只有在打开fabfile.py以查找特定任务时才能使用正确的PYTHONPATH,但一旦它导入了任务并开始实际运行,就会发生一些变化,因此它无法再访问原始文件夹。

我的黑客是不是该走了?但是,它不是破坏了封装吗,可以说是最后一个,因为fabfile.py应该知道它调用的任何函数或方法的所有间接依赖项?也许这是一个反对函数内部import语句的论点?

这是Fabric中的一个已知问题。Fabric在Github上的问题跟踪器中有几个问题。例如,请参阅第256期。

解决方案

你可以放

from secret import TEXT

在CCD_ 15的第一行或将当前目录添加到模块搜索路径中。

def another_hello():
import sys
sys.path.insert(0, '')
from secret import TEXT
print 'Hello, world!'
print 'text: ' + TEXT

最新更新