2009-06-16 5 views
12

Dans Python 2.6 (et versions antérieures), les fonctions intégrées hex() et oct() peuvent être surchargées dans une classe en définissant les fonctions spéciales __hex__ et __oct__. Cependant, il n'y a pas de fonction spéciale __bin__ pour surcharger le comportement de la nouvelle fonction intégrée bin() de Python 2.6.Can bin() peut être surchargé comme oct() et hex() dans Python 2.6?

Je veux savoir s'il y a un moyen de surcharger de manière flexible bin(), et sinon je me demandais pourquoi l'interface incohérente?

Je sais que la fonction spéciale __index__ peut être utilisée, mais ce n'est pas flexible car elle ne peut renvoyer qu'un nombre entier. Mon cas particulier d'utilisation est à partir du module bitstring, où zéro bits sont considérés comme significatifs:

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

Je pense qu'il n'y a pas moyen d'y parvenir, mais je pensais que ce ne serait pas de mal à demander!

Répondre

4

Je pense que la réponse courte est «Non, bin() ne peut pas être surchargé comme oct() et hex().

Quant à savoir pourquoi, la réponse doit se trouver avec Python 3.0, qui utilise __index__ surcharger hex(), oct() et bin(), et a supprimé les __oct__ et __hex__ fonctions spéciales tout à fait. Par conséquent, le Python 2.6 bin() ressemble beaucoup à une fonctionnalité Python 3.0 qui a été rétroportée sans trop réfléchir au fait qu'il fait les choses avec le nouveau Python 3 plutôt qu'avec l'ancien Python 2. Je suppose également qu'il est peu probable que cela soit corrigé, même si cela est considéré comme un bug.

1

La fonction bin reçoit sa valeur de la fonction __index__ de l'objet. Donc, pour un objet, vous pouvez définir la valeur convertie en binaire, mais vous ne pouvez pas définir le format de la chaîne.

0

Vous pouvez obtenir le même comportement que pour hex et octobre en remplaçant/remplacement intégré dans le bac() avec votre propre mise en œuvre qui a tenté d'appeler bin sur l'objet passé et est retombé à la poubelle standard () si l'objet n'a pas fourni bin. Cependant, étant donné qu'explicit est meilleur qu'implicite, coder votre application pour qu'elle dépende d'une version personnalisée de bin() n'est probablement pas une bonne idée, alors peut-être juste donner à la fonction un nom différent, par exemple. Quant à savoir pourquoi l'incohérence dans l'interface, je ne suis pas sûr. Peut-être que c'est parce que bin() a été ajouté plus récemment, donc c'est un léger oubli?

11

Comme vous l'avez déjà découvert, vous ne pouvez pas remplacer bin(), mais cela ne semble pas être nécessaire. Vous voulez juste une valeur binaire 0-padded. Malheureusement, dans python 2.5 et les versions précédentes, vous ne pouviez pas utiliser "% b" pour indiquer binaire, vous ne pouvez donc pas utiliser l'opérateur de formatage de chaîne "%" pour obtenir le résultat souhaité.

Heureusement python 2.6 offre ce que vous voulez, sous la forme de la nouvelle méthode str.format(). Je crois que ce bit particulier de la ligne bruit est ce que vous cherchez:

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

La syntaxe de ce mini-langue est sous « format specification mini-language » dans la documentation. Pour vous faire gagner du temps, je vais vous expliquer la chaîne que j'utilise:

  1. paramètre zéro (c.-à-19) doit être formaté, en utilisant
  2. magique « 0 » pour indiquer que je veux 0- nombre rembourré, aligné à droite, avec
  3. 10 chiffres de précision, en
  4. format binaire.

Vous pouvez utiliser cette syntaxe pour réaliser une variété de versions créatives d'alignement et de remplissage.

+0

Merci, c'est utile à savoir. J'ai déjà réussi à obtenir la sortie dans la forme que je voulais, je ne pouvais tout simplement pas obtenir la fonction bin pour me le renvoyer. Votre méthode str.format est considérablement plus concise que la méthode que j'ai utilisée! –

+0

Voir aussi http://stackoverflow.com/questions/3258330/converting-from-hex-to-binary-without-losing-leading-0s-python – endolith

Questions connexes