How to support% x formatting for a class that emulates an int

I have not seen a way to do this. I am in Python 3.6.1 (v3.6.1: 69c0db5050, March 21, 2017 01:21:04). MacOS under Sierra, although we will need this to work in Python 2.

I have a custom class that does something that looks like an int with a subfield extension. For my own reasons, I want to be able to do something like

inst * 4 

and

 inst.subfield << 1 

(where the subfield is an inst attribute). These objects are heavily overloaded and, for example, inst print will unload subfields for viewing.

All this is done by overloading all user functions to process math and interacting with other objects. In general, it works very well, with one glaring exception: print. For the most part, the user can forget that this is not an integer and use it as one, but using integer print commands will not work:

 print("%#x"%inst) TypeError: %x format: an integer is required, not CustomType 

I have __int__ overloaded, and int(inst) returns an integer as expected.

Is there any way to make this work? This is a slight annoyance, but I would like to fix it.

In addition, I have __format__ . So, '{0:x}'.format(inst) works, but the text above does not work.

Thanks!

+5
source share
1 answer

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 must losslessly convert a numeric object into an integer object (for example, in slicing, or in the built-in bin (), hex (), and oct () functions ). The presence of this method indicates that the numeric object is an integer type. You must return an integer.

So, __index__ is called hex() , as you can see by looking at the corresponding source code in PyNumber_ToBase .

+7
source

Source: https://habr.com/ru/post/1275717/


All Articles