2013-05-21 117 views
0

我有一個類,它定義了自己的__getattr__()以便與實例化對象包含的XML樹進行交互。這隱藏了用戶的XML結構,並允許他設置標籤值等,就好像它們是對象上的普通字段,並且適用於除一個之外的所有字段:名爲field的字段。以下是它的外觀:爲什麼Python尋找__members__而不是請求的字段?

>>> q = MyQuery() 
>>> q.file = "database" 
>>> print(q) 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<requestCollection xmlns="http://dwd.de/sky"> 
    <read> 
    <select> 
     <referenceDate> 
     <value></value> 
     </referenceDate> 
    </select> 
    <transfer> 
     <file name="my file"/> 
    </transfer> 
    </read> 
</requestCollection> 
>>> q.file 

工作正常,應該發生的副作用是這樣做的。但是,如果我嘗試設置字段field,則會得到該方法不應返回的字符串。爲了清楚起見,這是我的__getattr__一個簡化版本:

def __getattr__(self, key): 
    logging.info("Looking up value for key {}.".format(key)) 
    if key == "something" 
     return self.method_with_side_effect(key) 
    if key in field_list: 
     logging.info("Key is in the field list.") 
     return self.other_method_with_side_effects(key) 

ensemble_memberfield都在field_list。檢查了這一點:

>>> q = MyQuery() 
>>> q.ensemble_member 
Looking up value for key __members__. 
Looking up value for key __methods__. 
Looking up value for key ensemble_member. 
Key is in the field list. 
... Side effects ... 
>>> q.field 
'station' 
Looking up value for key __members__. 
Looking up value for key __methods__. 

的行爲ensemble_member是正確的,對於field這是完全不正確的。這是爲什麼?

我沒有方法,也沒有類/對象成員名爲field

另一個有趣的事情是,如果我把這個對__getattr__第一行:

def __getattr__(self, key): 
    if key == "field": 
     raise ValueError 

下仍然發生:

>>> q = MyQuery() 
>>> q.field 
'station' 
Looking up value for key __members__. 
Looking up value for key __methods__. 

這是怎麼回事?

+0

請張貼演示該問題的一個小的可運行的例子。另外,你使用的是哪個版本的Python? –

+0

你在某處叫「dir(q)」嗎? –

+0

我不會在任何地方調用dir(q),儘管我只是試了一下,「field」就在那裏。我不確定它是如何到達那裏的。 –

回答

1

我知道了 - 有問題的代碼是,到了最後,這些行:

class SkyQuery(object): 
    _unique_fields = ["parameter", 
         "ensemble", 
         "forecast", 
         "station"] 
    _field_tag_values = [field + "_value" for field in _unique_fields] 

命名臨時變量「場」在我的名單理解是造成問題。我完成後,Python正在保留它。這種行爲是一致的,我只是不期待它。

我在這裏看到三個解決方案(第三個是由user4815162342提出的)。我執行了第三個。

  1. 臨時變量重命名爲x而非field。然後我仍然有x作爲臨時變量浮動在我的代碼中,但因爲沒有成員應該被稱爲x它不會打擾我。

  2. 致電del(field)刪除該字段。我不喜歡打電話del(),我認爲它會混淆我的代碼,但如果我確實需要稍後才能訪問該變量,它就會工作。

  3. 更換髮電機表達list(field + "_value" for field in _unique_fields)列表理解不共享這個問題

+1

3.使用生成器表達式'list(field +「_value」for _unique_fields中的字段)'替換列表理解''不會共享此問題 – user4815162342

相關問題