2016-01-23 162 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實際上運行你輸入的代碼。它可以告訴對象的運行時類型是什麼,因爲分析是在運行時發生的。

相關問題