2012-10-14 43 views
1
Python 2.7.3 (default, Aug 1 2012, 05:14:39) 
[GCC 4.6.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import Image 
>>> im = Image.open("test.jpeg") 
>>> data = im.load() 
>>> data.__setitem__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'PixelAccess' object has no attribute '__setitem__' 
>>> help(data) 

>>> data.__setitem__ 
<method-wrapper '__setitem__' of PixelAccess object at 0x7f4d9ae4b170> 

這是我見過的最奇怪的事情。幫助()函數之前和之後python對象的屬性行爲不同

我在做與庫PIL的項目。 'data'是PixelAccess的一個對象。它在help(data)中具有__setitem__的屬性。

你可以做「data[x,y] = value」分配的像素值在座標(x,y)

Help on PixelAccess object: 

class PixelAccess(object) 
| Methods defined here: 
| 
| __delitem__(...) 
|  x.__delitem__(y) <==> del x[y] 
| 
| __getitem__(...) 
|  x.__getitem__(y) <==> x[y] 
| 
| __setitem__(...) 
|  x.__setitem__(i, y) <==> x[i]=y 

爲什麼不__setitem__以前help()功能存在,但之後出現?

它甚至在我執行快遞「data[x,y] = value」一樣。它僅在help()函數後出現。

如何解釋呢?

回答

1

事實上 - 這是somestrange行爲。 但問題不在於__getitem__不存在 - 它是存在的,只是暫時隱藏由於PIL代碼中的一些問題 - 可能是從允許延遲加載圖像的機制導致的錯誤。

這不應該麻煩你 - 你的情況「數據」是PIL的「PixelAccess」對象,它允許您使用的元組作爲索引來訪問您的圖像像素。它在其上執行「dir」時顯示「空」,如果你試圖獲取其__getitem__方法將引發一個屬性錯誤,確實是:

>>> from PIL import Image 
>>> img = Image.open("images/rock.png") 
>>> d1 = img.load() 
>>> dir (d1) 
[] 
>>> d1.__getitem__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'PixelAccess' object has no attribute '__getitem__' 
>>> # However, this works: 
... 
>>> d1[32,32] 
(255, 255, 255, 255) 
>>> d1.__getitem__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'PixelAccess' object has no attribute '__getitem__' 
>>> 

就像我說的,這就是紅外可能的副作用PIL使用 來創建PixelAcces對象。 如果您真的需要訪問您的PixelAccess.__getitem__方法,獲取方法 是繞過Python中大多數屬性隱藏技巧的方法:您使用 object__getattribute__方法來檢索它。

(而且一旦完成這種方式,驚訝的是,PixelAccess對象不再出現空目錄):

>>> dir(d1) 
[] 
>>> getattr(d1, "__getitem__") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'PixelAccess' object has no attribute '__getitem__' 
>>> object.__getattribute__(d1, "__getitem__") 
<method-wrapper '__getitem__' of PixelAccess object at 0x7f94e6f37170> 
>>> # there is our man 
... 
>>> getattr(d1, "__getitem__") 
<method-wrapper '__getitem__' of PixelAccess object at 0x7f94e6f37170> 
>>> # and this works now 
... 
>>> dir(d1) 
['__class__', '__delattr__', '__delitem__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__'] 
>>> 

總而言之,如上圖所示的object.__getattribute__通話應該是「確定性」爲您服務取得該方法。

至於在之前隱藏了什麼機制,以及導致它的原因和對象的所有其他成員在以這種形式進行內省後顯示,唯一知道的方法是挖掘PIL的代碼。

+0

感謝您的幫助。這是我第一次聽說「屬性隱藏」:-) – hbprotoss

+0

請給我看一些關於「attibute hiding」的搜索引用或關鍵詞嗎?我無法在Google上找到很多相關的東西 – hbprotoss

+0

這不是一個常見術語 - 我做了它 - 可以覆蓋類中的內省方法,不會在所有電路中返回結果。我試圖在Python中模擬「私有屬性」時遇到了這種情況:如果調用上下文不是同一個類中的方法,那麼方法會引發錯誤。在這種情況下,更可能是由於類是用C語言編寫的,而且沒有正確初始化 - Python在使用運算符時可以在__getitem__插槽中找到代碼,但是在觸發正確初始化之前什麼也沒有顯示。 – jsbueno

相關問題