Подтвердить что ты не робот

Может ли bin() быть перегружен как oct() и hex() в Python 2.6?

В Python 2.6 (и ранее) встроенные функции hex() и oct() могут быть перегружены в классе, определяя специальные функции __hex__ и __oct__. Однако не существует специальной функции __bin__ для перегрузки поведения встроенной функции 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'

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

  • параметр 0 (т.е. 19) должен быть отформатирован, используя
  • волшебный "0", чтобы указать, что я хочу 0-мягкое, выровненное справа число, с
  • 10 цифр точности,
  • двоичный формат.

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

Ответ 3

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

Ответ 4

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

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

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