2017-03-06 68 views
0

我正在使用客戶端提供的類(我無法訪問目標代碼),並試圖檢查對象是否具有屬性。該屬性本身是隻寫的,所以hasattr失敗:Python:檢查只寫屬性的類

>>> driver.console.con.input = 'm' 
>>> hasattr(driver.console.con, 'input') 
False 
>>> simics> @driver.console.con.input 
Traceback (most recent call last): 
File "<string>", line 1, in <module> 
Attribute: Failed converting 'input' attribute in object 
'driver.console.con' to Python: input attribute in driver.console.con 
object: not readable. 

是否有不同的方法來檢查,如果一個屬性存在?

+0

想到EAFP,你可以把它包裝在'try'塊中,除了'AttributeError',如果它不存在? – RichSmith

+0

如果您嘗試訪問您尚未創建的屬性,它會說「不可讀」嗎?如果是這樣,你可以檢查異常對象的消息是否包含「不可讀」。 – Blender

+0

@RichSmith目前我正在考慮攻擊這個問題。我也想知道這背後是什麼。 –

回答

3

你似乎有某種本地代碼代理的橋接Python來擴展,它是相當打破正常的Python約定

有兩種可能性:

  1. driver.console.con對象有一個命名空間實現屬性爲descriptors,而input描述符只有一個__set__ method(可能還有一個__delete__ method)。在這種情況下,尋找描述:

    if 'input' in vars(type(driver.console.con)): 
        # there is an `input` name in the namespace 
        attr = vars(type(driver.console.con))['input'] 
        if hasattr(attr, '__set__'): 
         # can be set 
         ... 
    

    這裏vars() function檢索用於driver.console.con類的命名空間。

  2. 代理使用__getattr__(或甚至__getattribute__)和__setattr__ hooks來處理任意屬性。您在這裏運氣不佳,您無法檢測到hasattr()之外的任何方法將支持哪些屬性,並嘗試直接設置該屬性。使用try...except防護:

    try: 
        driver.console.con.input = 'something' 
    except Attribute: # exactly what exception object does this throw? 
        # can't be set, not a writable attribute 
        pass 
    

    您可能需要使用調試器或print()語句來找出異常被拋出什麼(用try...except Exception as ex:塊來捕獲所有異常,然後檢查ex);在你的問題的回溯中,最後的異常信息看起來顯然是非標準的。那個項目真的應該在那個時候增加一個AttributeError

鑑於而自定義異常被拋出,我的錢是選擇2(可選件1仍是如果在描述符__get__方法拋出異常的可能性)。

+0

謝謝!我正在考慮嘗試...除了方法,但你的答案提供了一些額外的細節。感謝您的詳細解答! –