【问题标题】:PyDev importing from secondary source foldersPyDev 从辅助源文件夹导入
【发布时间】:2016-05-02 00:33:47
【问题描述】:

总结:使用 PyDev,我无法让一个 Python 模块 (FooTest) 在同一个 (test) 源文件夹中导入另一个 (FooMock)。

我有两个源文件夹和四个 Python 模块,目录结构如下。最小的示例代码在问题的末尾。虽然我提供了很多信息,但请不要让这吓到你 - 这是一个简单的问题场景。

PyDevProject/
  src/         (source folder for prod code)
    foo/
      __init__.py
      Bar.py
      Foo.py
  test/        (source folder for tests)
    foo/
      __init__.py
      FooMock.py
      FooTest.py

这里的问题是,当我尝试在 FooTest 模块中导入 FooMock 类时,我收到以下错误(运行 PyUnit 来运行 FooTest 测试):

Finding files... done.
Importing test modules ... Traceback (most recent call last):
  File "/Applications/Eclipse.app/Contents/Eclipse/plugins/org.python.pydev_4.5.4.201601292234/pysrc/_pydev_runfiles/pydev_runfiles.py", line 468, in __get_module_from_str
mod = __import__(modname)
  File "/Users/me/Development/krtiWorkspace/ImportTest/test/foo/FooTest.py", line 4, in <module>
    from foo.FooMock import FooMock
ImportError: No module named FooMock
ERROR: Module: FooTest could not be imported (file: /Users/me/Development/krtiWorkspace/ImportTest/test/foo/FooTest.py).
done.

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

我尝试过的事情:

  • 即使 FooMock 和 FooTest 都在同一个 Python 包中,也无法导入 FooMock。
  • 将 FooMock 移动到 src/ 目录下是有效的,即使放在一个唯一的 Python 包下(只要它在 src/ 下)。但这对我来说是不可接受的(在生产源文件夹中有测试代码)。
  • 我已确保 PyDev 中的 PYTHONPATH 设置设置为指定两个文件夹都是源文件夹。
  • 将 FooMock 代码复制并粘贴到 FooTest 代码中有效。但这对我来说是不可接受的(因为我想在其他地方引用 FooMock,在多个测试文件中,我不希望 FooMock 的多个副本因此浮动)。

对此我有什么办法吗?

代码:

# Code for Bar.py -----------------------------------------------------
class Bar(object):
    def __init__(self, foo):
        self.foo = foo
    def next(self):
        self.foo.incr()

# Code for Foo.py -----------------------------------------------------
class Foo(object):
    def __init__(self):
        self.num = 0
    def incr(self):
        self.num = self.num + 1

# Code for FooMock.py -------------------------------------------------
class FooMock(object):
    def mock_incr(self):
        self.hit = True

# Code for FooTest.py -------------------------------------------------
import unittest
from foo.Foo import Foo
from foo.Bar import Bar
from foo.FooMock import FooMock

class Test(unittest.TestCase):
    def test_Foo(self):
        foo = Foo()
        foo.incr()
        self.assertEquals(1, foo.num, "should be 1")
    def test_Bar(self):
        foo = FooMock()
        bar = Bar(foo)
        bar.next()

if __name__ == "__main__":
    unittest.main()

目录截图: Image showing directory structure and PYTHONPATH as previously explained

【问题讨论】:

    标签: python pydev python-unittest


    【解决方案1】:

    您的 PYTHONPATH 中有一个名为 foo 的模块两次。在第一个目录中,找到了包foo,确实没有名为FooMock的模块。

    你能把测试源目录下的模块foo重命名为别的吗?喜欢footests 而不是foo

    【讨论】:

    • 这就是问题所在!在这里,我假设这就像 Java。菜鸟失误。谢谢@grepe。为了确认,将 test/foo 包重命名为 test/footest 使 Python 能够找到 FooMock。
    • 我的问题的一个小扩展:所有 Python 包都必须是唯一的吗? IE。我可以有 SRC/foo.bar 和 TEST/tests.foo.bar 吗?无论如何,我现在正在检查。
    • 您可以在将包导入代码后对其进行扩展(这称为“猴子补丁”,请参见此 SO 主题,例如:stackoverflow.com/questions/5626193/what-is-a-monkey-patch)。但是 import 的工作方式是它按顺序在 PYTHONPATH 中包含的每个目录中查找包,一旦找到它,它就会停在那里。因此,如果包多次在路径中,则仅第一次包含它,并且仅使用第一个定义中的代码。
    • 我认为这与我的问题更相关:stackoverflow.com/questions/9207748/… 无论如何,再次感谢@grepe
    猜你喜欢
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多