Reputation: 30013
How does len work on Python?
Look at this example:
class INT(int):
pass
class STR(str):
def __len__(self):
return INT(42)
q = STR('how').__len__()
print q, type(q)
q = len(STR('how'))
print q, type(q)
The output is:
42 <class '__main__.INT'>
42 <type 'int'>
How can I handle it so len returns an INT instance?
Answers suggest that the only solution is overriding len
This is my alternative implementation. It doesn't seem very harmful.
original_len = len
def len(o):
l = o.__len__()
if isinstance(l, int):
return l
original_len(o)
Upvotes: 3
Views: 12214
Reputation: 10039
As others say, don't do this. Consider how usage of this class would look:
length = len(s) # the reader assumes `q` is an int.
length.in_yards() # the reader is going WTF?!
Instead of violating the reader's expectations, why don't you just add a different method:
s.length_in_yards()
P.S. Doesn't solve this question, but if you have a good reason to write custom integer-like objects, you might be interested in the __index__
special method that allows such object to be directly usable for indexing built-in sequences.
Upvotes: 3
Reputation: 8119
Do not do this. You need to learn when the best answer really is not to do what you are trying to do at all. This is one of those times.
Upvotes: 4
Reputation: 65599
You won't be able to. At least if you want it to work with the rest of python. See the definition of len
Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn’t define a nonzero() method and whose len() method returns zero is considered to be false in a Boolean context.
Italics emphasis mine.
Upvotes: 3
Reputation: 4253
I don't think you can, unless you write your own len. The builtin len always return an int.
Upvotes: 3