Advanced formatting with argument passing
list always uses repr on it's elements.
When you str or repr it.
And internally list is doing roughly the equivalent of what you are doing in format_array.

The only way to make this work is to use something like format_array,
or subclass list.
But they will both be doing the same thing, just depends on how much sugar you want.



Your code is nice, readable and follows PEP8.
As this is tending towards example code, it's not in it's native environment, it's hard to comment distinctively on it.

But format_data can be merged with the class.

class InsideB(object):
    def __init__(self, data):
        self.data = data

    def __repr__(self):
        data = self._data(True)
        return "InsideB(data={0})".format(data)

    def __format__(self, formatstr):
        data = self._data('x' in formatstr)
        return "InsideB(data={0})".format(data)

    def _data(self, as_hex):
        if as_hex:
            return binascii.b2a_hex(self.data).decode('ascii')
        else:
            return repr(self.data)


You can then add an option to use 'hex' or repr as the output type to the class.
With the option to reverting to the original after a use.
Obviously it depends on your usage.

class InsideB(object):
    def __init__(self, data, as_hex=False, revert_hex=False):
        self.data = data
        self._as_hex = as_hex
        self.output_type = as_hex
        self._revert_hex = revert_hex

    def _data(self, as_hex):
        if as_hex or self.output_type:
            data = binascii.b2a_hex(self.data).decode('ascii')
        else:
            data = repr(self.data)

        if self._revert_hex:
            self.output_type = self._as_hex

        return data


Then you would need to make a function that maps over all the items in the list,
changes output_type to what you want, and you'll be in the same position as you are now.
But with a bit more sugar.



If you choose to subclass list, and to use str in __str__,
then you'll get output which is just wrong.

&gt;&gt;&gt; print('{!s}, {!s}'.format('a', 'b'))
a, b
&gt;&gt;&gt; print('{!r}, {!r}'.format('a', 'b'))
'a', 'b'




No matter how I look at it you wont be able to change the output 'nicely'.
Unless you think something more robust to map(lambda i: i.output_type = True, array) is nice.

Bottom line you have to manually implement this, as repr is hard-coded.