Python pydev-ide抱怨模块导入本身

Python pydev-ide抱怨模块导入本身,python,pydev,Python,Pydev,注意:我没有接受答案,因为我真正的问题是为什么这会被标记为编译错误。我投票支持@Toreltwidler的答案,因为他给出了一个解决办法,但我想了解这个问题 我有一个包含自检代码的简单模块。为了便于在交互式会话中使用,自检代码会重新加载自身(模块) 这在PyDev(RunAs)和交互式窗口中都可以正常工作(在手动修改sys.path并导入之后);但是PydevIDE仍然在代码行中给出了一个“compile”/red-X错误 import Mod1 Iimport Mod1自其自身的原因是

注意:我没有接受答案,因为我真正的问题是为什么这会被标记为编译错误。我投票支持@Toreltwidler的答案,因为他给出了一个解决办法,但我想了解这个问题


我有一个包含自检代码的简单模块。为了便于在交互式会话中使用,自检代码会重新加载自身(模块)

这在PyDev(RunAs)和交互式窗口中都可以正常工作(在手动修改
sys.path
并导入之后);但是PydevIDE仍然在代码行中给出了一个“compile”/red-X错误

import Mod1  
I
import Mod1
自其自身的原因是名称必须在运行
Test()
的任何上下文中都可以解析,以便重新加载成功。例如,如果从一个新的交互式窗口导入
MyMain
,调用
reload
将在没有导入的情况下失败,因为名称Mod1未知

我有办法解决这个问题吗
Mod1
是一个大得多的项目的一部分,将其始终标记为不编译会使开发更加困难

出现问题的模块:

# Mod1.py
def Test():
    """ 
    run the self-test, but first force a reload of the module under test (this mod)
    """        
    import Mod1      # *****'COMPILE' ERROR HERE******  
    import imp
    Mod1 = imp.reload(Mod1)

    TestImpl()

def TestImpl():
    """
    self test here
    since I reload above, I can change this code and re-run from an interactive window
    this has to be a seperate function for the reload in Test to have an effect on this code
    """ 
    print(input("enter"))
额外的引导模块仅在PyDev中使用(因此我可以“作为”运行)

PyDev/Project PYTHONPATH(显示正确,此文件夹位于我的工作区的根目录下)。因为它确实在PyDev中运行,所以它肯定是正确的

/MyDirectory

谢谢

如果重新加载模块本身,则会创建一个无限循环,因为重新加载模块只是为了再次重新加载模块,等等

MyMain.py
中,您可以执行以下操作:

import Mod1
reload(Mod1)

Mod1.Test()

我想,如果没有进一步的代码示例,很难准确判断您为什么必须重新加载模块,但是如果必须这样做,那么应该可以(不在模块中执行)

我可能会同意Snaxib的答案,但是如果您希望保持当前的格式,您可以让Eclipse忽略该错误,方法是在行尾添加
#@unsoledImport
(点击Ctrl-1自动填充)。

从关于Snaxib答案的讨论中添加一个单独的答案,用于格式化

有一个模块不会更改,
TestMyStuff
,另一个模块会随更改而更新,
test

#TestMyStuff.py
def go():
    import TheTest
    reload(TheTest)
    TheTest.runTest()


现在,在iTreactive shell中,您应该能够运行
TestMyStuff.go()
,它将在每次运行时重新加载测试。在我的例子中,没有真正的解决方法,因为当使用pickle(我通过yaml间接使用它)时,正确的导入路径取决于模块的加载方式。如果要从模块外部取消对对象的pickle,则如果从内部执行pickle,则该操作将不起作用。自我导入为您提供了这种可能性。

我不确定是否同意-我正在从函数
测试中重新加载。很明显,如果调用void f(){f();}(C语法),您是在递归地使用hosed-但我不是这么做的。加载Mod1时,不会执行对导入Mod1的额外调用,不会进入无限循环。每个模块导入一次(当您使用
import
时-当然可以通过调用
reload
或其他方法强制重新导入),随后的导入只返回对结果模块对象的引用。@Snaxib如OP问题中所述,模块会重新加载自身,以便,在交互式终端中,测试可以在模块中的代码更改后运行,而无需从交互式窗口手动重新加载模块。您有一个很好的观点,您不一定要递归地重新加载模块。但是,最好从调用模块的位置重新加载模块,而不是在模块内部。这才更有意义。如果需要重新加载,请让
MyMain.py
重新加载它。您可以有条件地重新加载,但如果您从导入它的脚本重新加载它,它会更好(PyDev也不会对您大喊大叫)。@delnan-从技术上讲,您是正确的;但这在这里应该无关紧要。。。我没有递归加载模块。谢谢你的提示;这将在短期内帮助我。然而,这似乎是一个需要真正解决的问题。我的PYTHONPATH是正确的(至少PyDev会执行我的proj OK),并且
Mod1
在路径中。。。因此,它不应该抛出编译时错误。一个建议@Toreltwidler(谢谢)允许我抑制IDE错误-我现在正在使用它,但我觉得它实际上没有回答问题,因为这个错误对我来说似乎无效。另一个评论是,自导入的形式总是很差。我在这里的使用案例似乎可以接受——有人能说明这个惯例是否/为什么普遍不好吗?如果你认为自我导入总是不好的,那么我可以接受这个答案;然而,我不认为我的用例是多么糟糕,因此我觉得我应该能够让IDE停止抱怨(没有任何黑客攻击)。我在帖子中添加了一条评论,要求澄清这个风格问题)。谢谢@迈克,老实说,我不知道你自己进口是不是不好。我还要注意,我从来没有说过“总是”。但是,我假设为我使用的语言编写IDE的人比我更了解这种语言。您是在寻找一种使用Python避免此错误的方法,还是PyDev不再抱怨此错误的方法?如果是PyDev,那么您可能需要与他们一起创建一个bug报告。我要么希望PyDev不要抱怨,要么理解为什么我所做的是错误的:)我认为您是正确的,我需要与PyDev一起跟进。
#TestMyStuff.py
def go():
    import TheTest
    reload(TheTest)
    TheTest.runTest()
#TheTest.py
def runTest():
    #run my tests and change things often here.
    print(input("enter"))