Можно ли перегрузить bin () как oct () и hex () в Python 2.6? - PullRequest
13 голосов
/ 16 июня 2009

В Python 2.6 (и более ранних версиях) встроенные функции hex() и oct() могут быть перегружены в классе путем определения специальных функций __hex__ и __oct__. Однако нет специальной функции __bin__ для перегрузки поведения новой встроенной функции bin() в Python 2.6.

Я хочу знать, существует ли какой-либо способ гибкой перегрузки bin(), и если нет, то мне было интересно, почему несовместимый интерфейс?

Я знаю, что можно использовать специальную функцию __index__, но она не является гибкой, поскольку может возвращать только целое число. Мой конкретный пример использования взят из модуля bitstring , где начальные нулевые биты считаются значимыми:

>>> a = BitString(length=12)       # Twelve zero bits
>>> hex(a)
'0x000'
>>> oct(a)
'0o0000'
>>> bin(a)
'0b0' <------ I want it to output '0b000000000000'

Я подозреваю, что нет способа достичь этого, но я подумал, что не мешало бы спросить!

Ответы [ 4 ]

12 голосов
/ 18 июня 2009

Как вы уже обнаружили, вы не можете переопределить bin(), но это не похоже на то, что вам нужно это делать. Вы просто хотите двоичное значение с 0 дополнением. К сожалению, в python 2.5 и более ранних версиях вы не могли использовать «% b» для обозначения двоичного файла, поэтому вы не можете использовать оператор форматирования строки «%» для достижения желаемого результата.

К счастью, Python 2.6 предлагает то, что вы хотите, в форме нового метода str.format () . Я считаю, что именно этот бит шума линий - это то, что вы ищете:

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

Синтаксис этого мини-языка находится в разделе " спецификация формата мини-языка " в документации. Чтобы сэкономить время, я объясню строку, которую я использую:

  1. параметр нуля (т.е. 19) должен быть отформатирован с использованием
  2. волшебный "0", указывающий, что я хочу, чтобы число с нулевой добавкой было выровнено по правому краю, с
  3. 10 знаков точности, в
  4. двоичный формат.

Вы можете использовать этот синтаксис для создания разнообразных творческих версий выравнивания и отступов.

7 голосов
/ 06 июля 2009

Я думаю, что короткий ответ: «Нет, bin() не может быть перегружен, как oct() и hex()

Что касается того, почему, ответ должен лежать в Python 3.0, который использует __index__ для перегрузки hex(), oct() и bin(), и вообще удалил специальные функции __oct__ и __hex__.

Таким образом, Python 2.6 bin() выглядит очень похоже на то, что это действительно особенность Python 3.0, которая была перенесена обратно без особого рассмотрения, что она делает вещи новым способом Python 3, а не старым способом Python 2. Я также предположил бы, что это вряд ли будет исправлено, даже если это считается ошибкой.

1 голос
/ 16 июня 2009

Функция bin получает свое значение от функции __index__ объекта. Таким образом, для объекта вы можете определить значение, преобразованное в двоичное, но вы не можете определить формат строки.

0 голосов
/ 16 июня 2009

Вы можете добиться того же поведения, что и для hex и oct, переопределив / заменив встроенную функцию bin () своей собственной реализацией, которая пыталась вызвать bin для передаваемого объекта и отступила стандартная функция bin (), если объект не предоставил bin . Однако, исходя из того, что явное лучше, чем неявное, кодирование приложения в зависимости от пользовательской версии bin (), вероятно, не очень хорошая идея, поэтому, возможно, просто дайте функции другое имя, например

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

Что касается несоответствия в интерфейсе, я не уверен. Может быть, это потому, что bin () был добавлен совсем недавно, поэтому это небольшой недосмотр?

...