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>

これは私が今まで見た中で最も奇妙なことです。

私はライブラリPILでプロジェクトを行っています。' data'はのオブジェクトですPixelAccess__setitem__inの属性がありますhelp(data)

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()ます。

それをどのように説明しますか?

4

1 に答える 1

1

確かに-それは奇妙な振る舞いです。しかし、問題はそれが存在しないということで __getitem__はありません-それは存在し、PILコードの何らかの問題のために一時的に隠されています-おそらく画像の遅延読み込みを可能にするメカニズムに起因するバグです。

これで問題が発生することはありません。この場合の「データ」はPILの「PixelAccess」オブジェクトであり、タプルをインデックスとして使用して画像のピクセルにアクセスできます。__getitem__「dir」を実行すると「空」と表示され、そのメソッドを取得しようとすると属性エラーが発生します。実際、次のようになります。

>>> 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に対して空に見えなくなります):

>>> 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のコードを掘り下げることだけです。

于 2012-10-14T08:10:08.627 に答える