Pregunta

En Python 2.6 (y anteriormente), las funciones integradas hex () y oct () se pueden sobrecargar en una clase definiendo __hex __ y __oct__ funciones especiales. Sin embargo, no hay una función especial __bin__ para sobrecargar el comportamiento de la nueva función incorporada bin () de Python 2.6.

Quiero saber si hay alguna forma de sobrecargar de manera flexible bin () , y si no me preguntaba por qué la interfaz no es consistente.

Sé que se puede usar la función especial __index__ , pero esto no es flexible ya que solo puede devolver un número entero. Mi caso de uso particular proviene del módulo bitstring , donde los bits de cero iniciales se consideran significativos:

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

Sospecho que no hay forma de lograr esto, ¡pero pensé que no estaría mal preguntar!

¿Fue útil?

Solución 2

Creo que la respuesta corta es 'No, bin () no se puede sobrecargar como oct () y hex () . '

En cuanto a por qué, la respuesta debe estar en Python 3.0, que usa __index__ para sobrecargar hex () , oct () y < code> bin () , y ha eliminado las funciones especiales __oct__ y __hex__ por completo.

Por lo tanto, el bin () de Python 2.6 se parece mucho a que es realmente una característica de Python 3.0 que ha sido adaptada sin mucha consideración de que está haciendo las cosas de la manera de Python 3 en lugar del Python antiguo. 2 vías. También supongo que es poco probable que se solucione, incluso si se considera un error.

Otros consejos

Como ya descubrió, no puede anular bin () , pero no suena como si tuviera que hacerlo. Solo quieres un valor binario 0-rellenado. Desafortunadamente, en Python 2.5 y anteriores, no pudo usar "% b " para indicar binario, por lo que no puede usar el "% " operador de formateo de cadenas para lograr el resultado que desea.

Afortunadamente, Python 2.6 ofrece lo que usted desea, en la forma de la nueva str .format () método. Creo que lo que estás buscando es este ruido de línea en particular:

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

La sintaxis de este mini-lenguaje está bajo el formato " especificación de mini-idioma " en los docs. Para ahorrarle tiempo, le explicaré la cadena que estoy usando:

  1. el parámetro cero (es decir, 19 ) se debe formatear, usando
  2. a magic " 0 " para indicar que quiero un número 0-rellenado, alineado a la derecha, con
  3. 10 dígitos de precisión, en
  4. formato binario.

Puede utilizar esta sintaxis para lograr una variedad de versiones creativas de alineación y relleno.

La función bin recibe su valor de la función __index__ del objeto. Entonces, para un objeto, puede definir el valor convertido a binario, pero no puede definir el formato de la cadena.

Puede lograr el mismo comportamiento que para hex y oct al anular / reemplazar la función bin () incorporada con su propia implementación que intentó llamar a bin sobre el objeto que se pasa y volver a la función bin () estándar si el objeto no proporcionó bin . Sin embargo, sobre la base de que explícito es mejor que implícito, codificar su aplicación para que dependa de una versión personalizada de bin () probablemente no sea una buena idea, así que tal vez solo le dé un nombre diferente a la función, por ejemplo,

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

En cuanto a por qué la inconsistencia en la interfaz, no estoy seguro. Tal vez sea porque se agregó bin () más recientemente, por lo que es un descuido leve.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top