Vim的全自动补全在Python中对"from"导入失败
在Python中,当使用“from”导入时,自动补全功能似乎会失效,而正常的导入却没有问题。
举个例子,我有这两个文件:
Test.py:
class Test:
def method(self):
pass
main.py:
from Test import Test
class Test2:
def __init__(self):
self.x = Test()
如果我尝试对self.x使用自动补全,它会提示“找不到模式”。但是,如果我把导入语句改成:
import Test
并把self.x的声明改成:
self.x = Test.Test()
那么我就能正常使用自动补全了(比如它会建议“method”)。
我使用的是Vim 7.2.245和默认的Python代码补全插件(pythoncomplete)。我需要设置什么变量吗?还是说这种情况是正常的?
更新:
根据Jared的回答,我意外发现了一些事情:
自动补全在这个情况下不起作用:
from StringIO import StringIO
class Test:
def __init__(self):
self.x = StringIO()
self.x.<C-x><C-o>
s = Test()
但在这个情况下却可以正常工作:
from StringIO import StringIO
class Test:
def __init__(self):
self.x = StringIO()
self.x.<C-x><C-o>
s = Test()
s.x = StringIO()
唯一的区别是x的重新声明(实际上,如果我去掉__init__
里面的声明,它也能正常工作)。
我又测试了一下我的例子,我觉得问题不在于“from”导入,而是在另一个类中使用了导入的类。如果我把文件main.py
改成:
from Test import Test
class Test2:
def __init__(self):
self.x = Test()
self.x.<C-x><C-o>
y = Test()
y.<C-x><C-o>
第一次尝试使用自动补全失败,但第二次就正常了。所以看起来这可能是插件的一个bug :)
1 个回答
更新:哦,我查看了你的例子,发现我能完成
x = Test()
x.<C-x><C-o>
但是不能完成
o = object()
o.x = Test()
o.x.<C-x><C-o>
...我打算再深入研究一下
更新 2: 怪博士的复仇
然后...事情就变得奇怪了。
from StringIO import StringIO
class M:
pass
s = M()
s.x = StringIO()
s.x.<C-x><C-o>
可以完成。但是这个
from StringIO import StringIO
class M: pass
s = M()
s.x = StringIO()
s.x.<C-x><C-o>
你发现有什么不同吗? 在语法上没有 -- 只是多了一些空格
然而这却导致了完成失败。所以这里肯定有个解析的错误(为什么他们不直接使用 ast
模块,我也不知道...)
[更新结束]
乍一看,我无法重现你的问题;这是我的测试文件:
from os import path
path.<C-x><C-o>
我能完成。现在,我知道这并不完全是你的情况,但这表明 pythoncomplete 知道 'from'。
接下来是更深入的例子:
from StringIO import StringIO
s = StringIO()
s.<C-x><C-o>
而且...可以完成!你能试试这个例子,看看它在内置模块中是否对你有效吗? 如果是这样,你可能需要检查一下路径...
如果还是不行,而且你愿意深入研究,可以看看 pythoncomplete.vim 的第 555 行 [在我的 ubuntu 机器上是 /usr/share/vim/vim72/autoload/pythoncomplete.vim
]:
elif token == 'from':
mod, token = self._parsedotname()
if not mod or token != "import":
print "from: syntax error..."
continue
names = self._parseimportlist()
for name, alias in names:
loc = "from %s import %s" % (mod,name)
if len(alias) > 0: loc += " as %s" % alias
self.scope.local(loc)
freshscope = False
如你所见,这里处理 from
语句。
祝好