繁体   English   中英

python对象的属性在help()函数之前和之后的行为有所不同

[英]Attributes of python object behave differently before and after help() function

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的对象。 它在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()函数之前不存在,但出现在它之后?

即使执行express'data data[x,y] = value '也是如此。 它仅在help()函数之后出现。

怎么解释呢?

确实-这是一种奇怪的行为。 但是问题不在于__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显得为空):

>>> 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的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM