Can bin() be overloaded like oct() and hex() in Python 2.6?

只愿长相守 提交于 2019-12-03 02:05:52

As you've already discovered, you can't override bin(), but it doesn't sound like you need to do that. You just want a 0-padded binary value. Unfortunately in python 2.5 and previous, you couldn't use "%b" to indicate binary, so you can't use the "%" string formatting operator to achieve the result you want.

Luckily python 2.6 does offer what you want, in the form of the new str.format() method. I believe that this particular bit of line-noise is what you're looking for:

>>> '{0:010b}'.format(19)
'0000010011'

The syntax for this mini-language is under "format specification mini-language" in the docs. To save you some time, I'll explain the string that I'm using:

  1. parameter zero (i.e. 19) should be formatted, using
  2. a magic "0" to indicate that I want 0-padded, right-aligned number, with
  3. 10 digits of precision, in
  4. binary format.

You can use this syntax to achieve a variety of creative versions of alignment and padding.

I think the short answer is 'No, bin() can't be overloaded like oct() and hex().'

As to why, the answer must lie with Python 3.0, which uses __index__ to overload hex(), oct() and bin(), and has removed the __oct__ and __hex__ special functions altogether.

So the Python 2.6 bin() looks very much like it's really a Python 3.0 feature that has been back-ported without much consideration that it's doing things the new Python 3 way rather than the old Python 2 way. I'd also guess that it's unlikely to get fixed, even if it is considered to be a bug.

The bin function receives it's value from the object's __index__ function. So for an object, you can define the value converted to binary, but you can't define the format of the string.

You could achieve the same behaviour as for hex and oct by overriding/replacing the built in bin() function with your own implementation that attempted to call bin on the object being passed and fell back to the standard bin() function if the object didn't provide bin. However, on the basis that explicit is better than implicit, coding your application to depend on a custom version of bin() is probably not a good idea so maybe just give the function a different name e.g.

def mybin(n):
    try:
        return n.__bin__()
    except AttributeError:
        return bin(n)

As for why the inconsistency in the interface, I'm not sure. Maybe it's because bin() was added more recently so it's a slight oversight?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!