I haven't seen a way to do this. I am in Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04). MacOS under Sierra, though we'll need this to work on Python 2.
I have a custom class which does something which looks like an int with subfield decoding. For my own reasons, I want to be able to do things both like
inst * 4
and
inst.subfield << 1
(where subfield is an attribute of inst). These objects are highly overloaded, and e.g. printing inst
will dump the subfields for viewing.
This is all done by overloading all the custom functions to handle the math and interaction with other objects. In general, it works really well, with one glaring exception: printing. For the most part, a user can forget this isn't really an integer and use it like one, but using the integer print commands won't work:
print("%#x"%inst)
TypeError: %x format: an integer is required, not CustomType
I do have __int__
overloaded, and int(inst)
returns an integer as expected.
Is there any way to make this work? It's a minor annoyance, but one I'd like to fix.
Also, I do have __format__
implemented. So '{0:x}'.format(inst)
works, but the print above doesn't.
Thanks!
You need to implement __int__
and __index__
:
class X(object):
def __int__(self):
return 42
def __index__(self):
return 42
x = X()
print('%#x' % x)
output:
0x2a
From the docs for __index__
:
Called to implement operator.index(), and whenever Python needs to losslessly convert the numeric object to an integer object (such as in slicing, or in the built-in bin(), hex() and oct() functions). Presence of this method indicates that the numeric object is an integer type. Must return an integer.
So __index__
is called by hex()
, as can be seen by looking at the relevant source code in PyNumber_ToBase.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With