2016-01-23 139 views
2

我是Python新手,我非常喜欢这种语言。但是最近我在Eclipse中使用PyDev时遇到了一个恼人的问题。返回的python对象方法的Intellisense

一些方法返回一些类的一个实例。但我无法获得实例方法的智能感知。

例如:

import openpyxl 
from openpyxl.reader.excel import load_workbook 
from openpyxl.worksheet import Worksheet 


xlsFile='hello.xlsx' 
wbook = load_workbook(xlsFile) 

wsheet1=wbook.get_sheet_by_name('mysheet') 
wsheet1.cell('A9').hyperlink=r'\\sharefolder' 

wsheet2=Worksheet() 
wsheet2.cell('A1').hyperlink=r'\\sharefolder' 

在这段代码中,我可以得到方法cell()提示与wsheet2,但不与wsheet1。虽然他们都是我已经导入的Worksheet类型。看来Python或PyDev无法正确检测返回对象的类型。

这是语言限制吗?还是有什么我做错了?现在,我必须深入研究源代码,看看返回值的实际类型是什么。然后检查该类型中定义的方法。这非常乏味。

我写了一个小测试来重现这个问题。奇怪的是,intellisense似乎工作。

enter image description here

回答

1

当然,从技术上Python中的方法可以返回任何东西和操作的结果,只有当操作完成定义。在函数执行结束

def f(a): 
    if a == 1: 
     return 1 # returns int 
    elif a == 2: 
     return "2" # returns string 
    else: 
     return object() # returns an `object` instance 

功能是相当有效的Python和它的结果被严格定义,但只有

考虑这个简单的功能。确实如此:

>>> type(f(1)) 
<type 'int'> 
>>> type(f(2)) 
<type 'str'> 
>>> type(f(3)) 
<type 'object'> 

当然,这种灵活性是一直不需要的东西,大多数方法都会返回一些可预测的先验。一个智能的IDE可以分析代码(以及其他一些提示,例如可能指定参数和返回类型的文档字符串),但这总是以一定的置信度进行猜测。另外还有PEP0484,它在语言层面引入了类型提示,但它是可选的,相对较新的,所有遗留代码都绝对不使用它。

如果PyDev的不特定的情况下工作,很好,这是一个遗憾,但它的东西,如果你选择像Python这样的动态语言,你应该接受。也许值得尝试一个不同的,更智能的IDE,或者在IDE旁边打开一个具有交互式Python提示符的控制台,以便即时测试您的代码。我会建议使用复杂的蟒蛇像贝壳bpython

2

这是一个事实,即Python是动态类型的结果。

在诸如C#的静态类型语言中,方法是注释为及其类型签名。 (另外:在某些系统类型中,可以使用类型检查程序推断)。编译器知道函数的返回类型以及参数所需的类型,而无需运行代码,因为您已将类型写下来!这使您的工具不仅可以检查程序的类型,还可以构建有关程序中方法及其类型的元数据;智能感知通过查询从您的程序文本中收集的元数据来工作。


Python没有内置到该语言中的静态类型系统。这使得工具难以在不运行代码的情况下提供提示。例如,这个函数的返回类型是什么?

def spam(eggs): 
    if eggs: 
     return "ham" 
    return 42 

有时候spam返回一个字符串;有时它会返回一个整数。 Intellisense将在spam的呼叫的返回值上显示哪些方法?

该课程有哪些可用的属性?

class Spam: 
    def __getattr__(self, name): 
     if len(name) > 5: 
      return "foo" 
     return super().__getattr__(name) 

Spam有时动态生成的属性:应该怎样智能感知显示器的Spam一个实例?

在这些情况下没有正确答案。您可能可以自愿进行一些猜测(例如,您可以在spam的返回值中显示包含strint的方法的列表),但您无法提供始终正确的建议。


因此,针对Python的Intellisense工具简化为最佳猜测。在您提供的示例中,您的IDE不知道有关返回类型get_sheet_by_name的足够信息,以便为您提供有关wsheet1的信息。但是,它确实知道wsheet2的类型,因为您只是将其实例化为Worksheet。在第二个例子中,Intellisense通过检查其源代码来简单地猜测返回类型f1

顺便提一下,在像IPython这样的交互式shell中自动完成更可靠。这是因为IPython实际上运行你输入的代码。它可以告诉对象的运行时类型是什么,因为分析是在运行时发生的。