Reputation:
This returns what you'd expect:
class My(object):
def __len__(self):
return 6
a = My()
print(len(a))
But this throws an error:
class My2(object):
pass
b = My2()
b.__len__ = lambda x: 6
print(len(b))
TypeError: object of type 'My2' has no len()
Why?
Upvotes: 2
Views: 65
Reputation: 2884
It is because you are trying to define the method on the instance not on the underlying class. For example, this would work:
class My2(object):
pass
b = My2()
b.__class__.__len__ = lambda x: 6
print(len(b)) # Prints 6
Furthermore to clarify the comments, it is not a matter of it being a lambda or a function as proven by this not working:
class My2(object):
pass
def l(x):
return 6
b = My2()
b.__len__ = l
print(len(b)) # TypeError: object of type 'My2' has no len()
Upvotes: 4
Reputation: 16958
In Python len(a)
as other "magic" functions, is a shorthand for type(a).__len__(a)
.
Therefore the function (as opposed to method) __len__
you define on the instance b
cannot be accessed through len
since the call would be resolved as:
type(b).__len__(b)
But type(b)
doesn't have a method __len__
.
I asked a similar question and got a very good answer here
The documentation is worth reading. Your example is almost identical.
Upvotes: 1