代码之家  ›  专栏  ›  技术社区  ›  Louis Thibault

为什么不能从当前工作目录中导入模块?

  •  1
  • Louis Thibault  · 技术社区  · 6 年前

    请考虑以下测试用例。

    foo
    ├── foo
    │   ├── __init__.py
    │   └── bar.py
    └── test.tac
    

    bar.py 包含一个简单的类定义:

    # bar.py
    class Bar:
        pass
    

    test.tac ,Twisted应用程序配置文件包含一个import语句:

    #test.tac
    from foo.bar import Bar
    

    运行时 twistd -ny test.tac ,我得到以下错误:

    $ twistd -ny test.tac
    Unhandled Error
    Traceback (most recent call last):
      File "/Users/lthibault/.pyenv/versions/3.6.2/lib/python3.6/site-packages/twisted/application/app.py", line 674, in run
        runApp(config)
      File "/Users/lthibault/.pyenv/versions/3.6.2/lib/python3.6/site-packages/twisted/scripts/twistd.py", line 25, in runApp
        runner.run()
      File "/Users/lthibault/.pyenv/versions/3.6.2/lib/python3.6/site-packages/twisted/application/app.py", line 381, in run
        self.application = self.createOrGetApplication()
      File "/Users/lthibault/.pyenv/versions/3.6.2/lib/python3.6/site-packages/twisted/application/app.py", line 453, in createOrGetApplication
        application = getApplication(self.config, passphrase)
    --- <exception caught here> ---
      File "/Users/lthibault/.pyenv/versions/3.6.2/lib/python3.6/site-packages/twisted/application/app.py", line 464, in getApplication
        application = service.loadApplication(filename, style, passphrase)
      File "/Users/lthibault/.pyenv/versions/3.6.2/lib/python3.6/site-packages/twisted/application/service.py", line 416, in loadApplication
        application = sob.loadValueFromFile(filename, 'application')
      File "/Users/lthibault/.pyenv/versions/3.6.2/lib/python3.6/site-packages/twisted/persisted/sob.py", line 177, in loadValueFromFile
        eval(codeObj, d, d)
      File "test.tac", line 1, in <module>
        from foo.bar import Bar
    builtins.ModuleNotFoundError: No module named 'foo'
    
    
    Failed to load application: No module named 'foo'
    

    这很令人惊讶,因为 python test.tac 测试.tac 具体如下:

    from sys import path
    print(path)
    from foo.bar import Bar
    

    python <filename> 在运行时将当前工作目录前置到路径 twistd <filename> 没有。

    1. 这是个错误,还是有充分的理由 twistd 这样做?
    2. 建议的解决方法是什么 扭曲的
    2 回复  |  直到 6 年前
        1
  •  0
  •   user2357112    6 年前

    Python中没有规则规定工作目录应该在路径上。相反,在默认情况下,Python将 主脚本 在路上。当你跑的时候 python test.tac ,该目录是工作目录,但是当您运行twistd时,主Python脚本是Twisted的一部分,它不在工作目录中。

    由于我不熟悉Twisted,所以我不能说您应该使用什么样的代码组织和Twisted配置组合来使这个导入工作。

        2
  •  0
  •   sherpya    6 年前

    import os
    import sys
    
    sys.path.append(os.path.abspath(os.path.dirname(__file__)))
    
    from foo.bar import Bar