Bug? If not, how to work around it?
Bengt Richter
bokr at oz.net
Thu Aug 7 22:19:27 EDT 2003
On 7 Aug 2003 15:54:33 -0700, mis6 at pitt.edu (Michele Simionato) wrote:
>Alex Martelli <aleax at aleax.it> wrote in message news:<t%vYa.29160$an6.1020776 at news1.tin.it>...
>> "__getattr__ is skipped" is false (the
>> __getattr__ a *metaclass* could define would indeed be used as
>> equivalent to the class defining methods) -- the _class_'s __getattr__
>> if any is irrelevant because it's used on class *instances* (as
>> the language reference also says a few pages later) and thus it's
>> not the *CLASS* that's defining "methods with special names" here.
>>
>
>Alex, did you look at the thread I mentioned? Here is the problem
>with __getattr__ in metaclasses for special methods (quoting from
>that thread).
>
>"""
>defining __len__ on the class does not work:
>
>class M(type):
> def __getattr__(self,name):
> if name=='__len__': return lambda self:0
>
>class F: __metaclass__=M
>
>>>> f=F()
>>>> F.__len__(f) # okay 0
>>>> len(f) # TypeError: len() of unsized object
>f.__len__() # AttributeError: 'F' object has no attribute '__len__'
>
>As you see, the problem is that len(x) is not calling x.__len__(),
>nor x.__class__.__len__(x); I really would like to know how ``len``
>(or ``str``, ``repr``, etc.) work.
>"""
Not very tested, but maybe you have to write it something like this:
>>> class M(type):
... def __new__(cls, name, bases, cdict):
... cdict['__len__'] = lambda self:0
... return type.__new__(cls, name, bases, cdict)
...
>>> class F: __metaclass__ = M
...
>>> f=F()
>>> F.__len__
<unbound method F.<lambda>>
>>> F.__len__(f)
0
>>> len(f)
0
>>> hasattr(M,'__len__')
False
>>> hasattr(F,'__len__')
True
Or am I missing the point? ;-/
>
>If you remember, Bjorn Pettersen reported this (or something similar)
>months ago. I am saying that this behaviour is not documented, at
>least AFAIK.
>
Regards,
Bengt Richter
More information about the Python-list
mailing list