PyDev中的虚假未解决导入错误

5
PyDev报告不存在的导入错误。 最初的症状是虚假的“未解决的导入”错误,这些错误通过以下某种组合得到解决:
- 清理项目 - 重新索引项目(删除解释器,再次添加) - 重启Eclipse - 向Python神灵烧香
现在的错误是“来自导入的未经验证的变量”--似乎找不到pymssql.connect。
这不是PYHTONPATH问题。 我可以完全正常地访问模块,文件中带有(所谓的)错误的代码运行良好---它具有单元测试和生产代码调用它。
错误在PyDev中:我向我的PyDev项目添加了一个新模块,错误仅发生在新模块中。 我已经尝试了上述所有操作。
因此,我计划在其他地方发布此代码以征求有关设计的评论,并在评论中被要求发布代码。 (受启发于:Database connection wrapper和Clint Miller对此问题的回答:How do I correctly clean up a Python object?)。导入错误发生在第69行(self.connection = pymssql.connect ...)。 不确定这对回答问题有何好处,但...
import pymssql
from util.require_type import require_type

class Connections(object):
    @require_type('host', str)
    @require_type('user', str)
    @require_type('password', str)
    @require_type('database', str)
    @require_type('as_dict', bool)
    def __init__(self, host, user, password, database, as_dict=True):
        self.host = host
        self.user = user
        self.password = password
        self.db = database
        self.as_dict = as_dict

    @staticmethod
    def server1(db):
        return Connections('','','','')

    @staticmethod
    def server2(db):
        pass

    @staticmethod
    def server3(db):
        pass


class DBConnectionSource(object):
    # Usage:
    #        with DBConnectionSource(ConnectionParameters.server1(db = 'MyDB)) as dbConn:
    #            results = dbConn.execute(sqlStatement)

    @require_type('connection_parameters', Connections)
    def __init__(self, connection_parameters=Connections.server1('MyDB')):
        self.host = connection_parameters.host
        self.user = connection_parameters.user
        self.password = connection_parameters.password
        self.db = connection_parameters.db
        self.as_dict = connection_parameters.as_dict
        self.connection = None

    def __enter__(self):

        parent = self

        class DBConnection(object):
            def connect(self):
                self.connection = pymssql.connect(host=parent.host,
                                                  user=parent.user,
                                                  password=parent.password,
                                                  database=parent.db,
                                                  as_dict=parent.as_dict)

            def execute(self, sqlString, arguments={}):
                if self.connection is None:
                    raise Exception('DB Connection not defined')
                crsr = self.connection.cursor()
                crsr.execute(sqlString, arguments)
                return list(crsr)

            def cleanup(self):
                if self.connection:
                    self.connection.close()

        self.connection = DBConnection()
        self.connection.connect()
        return self.connection

    def __exit__(self, typ, value, traceback):
        self.connection.cleanup()

我很乐意帮忙,只是不知道该发布什么内容,除了一个导入语句(import pymssql)和一个函数调用(pymssql.connect)之外。我相当确定这是PyDev环境问题,因为我可以正常运行我编写的代码。 - BenDundee
我猜测你指的是显示导入语句的前几行,让我们知道你正在导入哪个版本的 eggs + Python 版本 + PyDev 版本 + Eclipse 版本。 - Woot4Moo
`>>> import pymssql
pymssql.version '2.0.0'`
- BenDundee
同时还有:Python 2.7.3、Eclipse 4.2、PyDev 2.7.1。抱歉,我以为已经在原始帖中提到了这些。 - BenDundee
3个回答

1
尝试在出错的那一行使用ctrl+1,并添加一条注释说明你期望导入该项。这应该可以解决PyDev错误,因为它执行的是静态代码分析而不是运行时分析。

所以,我正在使用Mac。我尝试了Command-1,它给了我一个选项列表:'创建方法','创建类'和'@UndefinedMethod'。单击最后一个选项不会有任何反应。 - BenDundee
@BenDundee,你去到出问题的那一行了吗?应该有一个选项,上面写着忽略错误或添加注释。 - Woot4Moo
@BenDundee 我会在下班后在家里的环境中检查这个。 - Woot4Moo
@BenDundee 噢,我明白你现在在哪了,到导入那行代码并让我看看截图。 - Woot4Moo
它找到了模块,只是似乎没有正确地对其进行索引。 - BenDundee

1

简短版本:阅读第五个灰色框。

你的问题(和我的)似乎是由于多级导入未被正确处理而引起的。在某个地方,链接丢失了。

假设你有一个文件

foo/bar.py

而在该文件中,您有一个名为的符号

wazoo=15

如果您尝试以下操作:
from foo import bar
from bar import wazoo <-- false error here

或者,如果您尝试使用:

from foo import bar
...
i = bar.wazoo <-- false error here

你可能会在 "wazoo" 上遇到虚假的未解决错误。由于这是一个 bug,显然不一致。
但是,如果你按照以下步骤操作:
from foo.bar import wazoo

问题似乎确实消失了。
另外,我注意到,这有时会发生在导入文件中新定义的符号中。 此外,该文件中某些符号的早期错误将神奇地消失,只剩下新错误。这意味着可能存在某种状态文件,并且即使您“构建所有”等操作,也未被清除。
还要注意的是,当我使用Python枚举hack时,这个问题似乎最容易发生...也许这会为PyDev-elopers提供线索(甚至是否仍在维护PyDev):

bar.py:

def enum(**enums):
  return type('Enum', (), enums)

SOMETHING = enum(A=1, B=2)

someotherfile.py:

from foo import bar
from bar import SOMETHING
...
x = SOMETHING.A

0

我在引发错误的行末添加了# @UndefinedVariable。

这并不是一个永久性的解决方案,但至少暂时消除了屏幕上的红色。如果有更好的长期解决方案,我很乐意听取建议。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接