[ python-Bugs-1382740 ] len() on class broken
SourceForge.net
noreply at sourceforge.net
Fri Dec 16 23:52:25 CET 2005
Bugs item #1382740, was opened at 2005-12-16 13:18
Message generated for change (Settings changed) made by kquick
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1382740&group_id=5470
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Interpreter Core
Group: Python 2.4
>Status: Open
Resolution: Invalid
Priority: 5
Submitted By: Kevin Quick (kquick)
Assigned to: Nobody/Anonymous (nobody)
Summary: len() on class broken
Initial Comment:
With the following python input:
class A:
@classmethod
def __len__(cls):
return 12
print '1',A.__len__()
print '2',A().__len__()
print '3',len(A())
print '4',len(A)
The output always breaks for '4' with 'TypeError: len
of unsized object'
Same result for @staticmethod or normal instance method
declaration.
----------------------------------------------------------------------
>Comment By: Kevin Quick (kquick)
Date: 2005-12-16 15:52
Message:
Logged In: YES
user_id=6133
That would indeed solve '4', but has a non-orthogonality of
attribute propagation that I don't understand and which
seems inconsistent.
In my original:
'1' demonstrates that __len__ is indeed in the dictionary
for the class.
'2' shows the expected attribute propagation effects: if
at attribute is not found in the instance dictionary,
the class dictionary is checked.
'3' shows that len is implemented (generally) by looking
for a __len__ method on the object in question.
'4' confuses me, because it means that '3' isn't quite
correct...
With your metaclass solution (using "__metaclass__ = meta"
:) it does indeed make '4' work, and '1', but '2' and '3'
now do not work, showing that instance-->class propagation
does not follow instance-->class-->metaclass. Or something
...
Approaching this a different way:
My understanding of @classmethod (or perhaps more properly
@staticmethod) is that it allows "constant" methods that are
independent of the particular object instance. So if I had:
class C:
@staticmethod
def f(): return 1
then both C.f() and C().f() are valid and return 1.
Why the len() translation to __len__ works *differently*
is strange. I'm still defining a method, just one that
I want Python to use for any len(A) or len(A()) refs,
translating those to A.__len__() or A().__len__() and using
those just as for C and f, respectively.
----------------------------------------------------------------------
Comment By: Reinhold Birkenfeld (birkenfeld)
Date: 2005-12-16 14:43
Message:
Logged In: YES
user_id=1188172
You want to use a metaclass:
class meta(type):
def __len__(cls):
return 12
class B:
__metaclass__ = B
print len(B)
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1382740&group_id=5470
More information about the Python-bugs-list
mailing list