简体   繁体   English

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

[英]Why can't twistd import a module from it's current working directory?

Please consider the following test case. 请考虑以下测试案例。

The project directory is structured thusly: 项目目录的结构如下:

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

bar.py contains a trivial class definition: bar.py包含一个简单的类定义:

# bar.py
class Bar:
    pass

test.tac , the Twisted Application Configuration file, contains a single import statement: test.tac (Twisted应用程序配置文件)包含一个导入语句:

#test.tac
from foo.bar import Bar

When running twistd -ny test.tac , I obtain the following error: 运行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'

This is very surprising because python test.tac produces no error. 这非常令人惊讶,因为python test.tac产生错误。 In order to further debug, I modified test.tac as follows: 为了进一步调试,我对test.tac进行了如下修改:

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

This revealed that running python <filename> prepends the current working directory to the path whereas running twistd <filename> does not. 这表明运行python <filename>会将当前工作目录添加到路径前,而运行twistd <filename>则不会。

My question is twofold: 我的问题是双重的:

  1. Is this a bug, or is there a good reason for twistd to behave this way? 这是一个错误,还是有充分的理由twistd这种行为?
  2. What is the recommended way of fixing this in twistd . 建议使用twistd方式修复此问题的方法是什么 Is there some sort of option I can set or does it need to be done manually? 我可以设置某种选项吗?还是需要手动完成?

There is no rule in Python saying the working directory should be on the path. Python中没有规则说工作目录应该在路径上。 Rather, by default, Python puts the directory of the main script on the path. 相反,默认情况下,Python将主脚本的目录放在路径上。 When you run python test.tac , that directory is the working directory, but when you run twistd, the main Python script is some part of Twisted, which does not lie in the working directory. 当您运行python test.tac ,该目录是工作目录,但是当您运行twisted时,主要的Python脚本是Twisted的一部分,它不在工作目录中。

As I am unfamiliar with Twisted, I cannot say what combination of code organization and Twisted configuration you're supposed to use to make this import work. 由于我不熟悉Twisted,因此无法说出应该使用哪种代码组织和Twisted配置的组合来实现此导入。

this snippet will add directory containing the tac file to python path 此代码段会将包含tac文件的目录添加到python路径

import os
import sys

sys.path.append(os.path.abspath(os.path.dirname(__file__)))

from foo.bar import Bar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM