核心编程(2sec)中的疑问

核心编程(2sec)中的疑问

最近2天浏览了一部分core programming,遇到了以下疑问,期待哪位朋友提示指导一下:
章节:13.15 Delegation
其中有'Simple Example Wrapping Any Object' sector:
....
class WrapMe(object):
    def __init__(self, obj):
        self.__data = obj
    def get(self):
        return self.__data
    def __repr__(self):
        return 'self.__data'
    def __str__(self):
        return str(self.__data)
    def __getattr__(self, attr):
        return getattr(self.__data, attr)
.....
>>> wrappedComplex = WrapMe(3.5+4.2j)
    >>> wrappedComplex                # wrapped object: repr()
    (3.5+4.2j)
...
Once we create our wrapped object type, we obtain a string representation, silently using the call to repr()...。
####################################################默认的是repr(),python中对所有类型都是这样?还有什么时候用str及如何用?如果我想把str设置成默认的,又怎么处理?####################################################
...
Special behaviors that are not in a type's method list will not be accessible since they are not attributes. One example is the slicing operations of lists which are built-in to the type and not available as an attribute like the append() method, for example. Another way of putting it is that the slice operator ( [ ] ) is part of the sequence type and is not implemented through the __getitem__() special method.
...
wrappedList = WrapMe([123, 'foo', 45.67])
....
   >>> wrappedList[3]
   Traceback (innermost last):
     File "<stdin>", line 1, in ?
     File "wrapme.py", line 21, in __getattr__
       return getattr(self.data, attr)
   AttributeError: __getitem__

...
However, we can always cheat by accessing the real object [with our get() method] and its slicing ability instead:

   >>> realList = wrappedList.get()
   >>> realList[3]
   'bar'
#############################################对上述我不是很明白:
wrappedList[3]:
是不是__getattr__先搜索local/class namespaces(也就是WrapMe),失败然后再去找list默认的函数,没有相应的默认函数,出现异常
realList = wrappedList.get()
realList[3]
我觉得这个开始直接去List的默认函数表里去找,然后再去built-in空间?
不知道我这个理解对不对

Thanks in advance

没人指导指导啊?
limou大人呢
这个主要意思就是说明有些方法与属性是不一样,比如分片,下标[3]这种,通过__getattr__是无法处理的。
__getattr__的搜索名字空间是什么呢?built-in ?global?也就是说他从哪里去找所要的object?


QUOTE:
原帖由 limodou 于 2008-7-15 17:03 发表
这个主要意思就是说明有些方法与属性是不一样,比如分片,下标[3]这种,通过__getattr__是无法处理的。

那为什么通过get()后就可以呢?
__getattr__是你写的方法,你返回什么已经什么。

使用get()后因为它返回的是底层的__data呀。已经不是原来的对象了。
Thanks for limodou's reply and help:
could i understand it like this?:
if i overrode the __getattr__ in the wrapped class,like the above,did it just look up the attribute in the class and the instance of the class,if the lookup failed,then it emit the exception?
while if i don't override __getattr__,it first would look up attributes in instance or class(es),if the lookup fails,then __getattr__ in built-in namespace will be called(i learned it from python reference ).
No, just as I said, __getattr__ is written by you, you should consider how to deal with return values. So you can find in the scope of current object or find in other underlying object you want to access.

And you should raise exception when the lookup failure. If you don't override __getattr__, python will do it for you. If not find a attribute, it'll throw exception.


QUOTE:
原帖由 limodou 于 2008-7-16 14:15 发表
No, just as I said, __getattr__ is written by you, you should consider how to deal with return values. So you can find in the scope of current object or find in other underlying object you want t ...

Yes,__getattr__ do what i defined it to do.
if i don't override it,where will it to dive into to look up attribute after instance or class(es)?built-in namespace or others(memory or)?

For the above example:
...
def __getattr__(self, attr):
        return getattr(self.__data, attr)
...
could i think getattr just look attribute in the __data(intance or it's class(es)  ),if attribute isn't found here,then raise the exception?

Thanks very much
Because __getattr__ doesn't exist by default, so if you don't define it yourself, it won't exist at all. You can see:

[Copy to clipboard] [ - ]
CODE:
>>> class A(object):pass
...     
>>> dir(A)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']

There is no __getattr__ at all. And for obj.X, python will search attribute 'X' according to MRO(Method Resolution Order) rule, you can see this document http://www.python.org/download/releases/2.3/mro/. If Python can't find the attribute, it'll raise exception.