2009-06-16 5 views
12

W języku Python 2.6 (i wcześniejszych) funkcje wbudowane hex() i oct() mogą być przeciążone w klasie, definiując specjalne funkcje __hex__ i __oct__. Jednak nie ma specjalnej funkcji __bin__ do przeciążania zachowania nowej wbudowanej funkcji Pythona 2.6, bin().Czy bin() może być przeciążony, podobnie jak oct() i hex() w Pythonie 2.6?

Chcę wiedzieć, czy istnieje jakikolwiek sposób elastycznego przeciążania bin(), a jeśli nie, zastanawiałem się, dlaczego niespójny interfejs?

Wiem, że można użyć specjalnej funkcji __index__, ale nie jest to elastyczne, ponieważ może zwracać tylko liczbę całkowitą. Moja szczególności przypadek użycia jest z modułu bitstring, gdzie wiodące zero bity są uznawane za znaczące:

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

Podejrzewam, że nie ma sposobu, aby to osiągnąć, ale pomyślałem, że nie zaszkodzi się zapytać!

Odpowiedz

4

Myślę, że krótka odpowiedź brzmi "Nie, bin() nie może być przeciążona, jak oct() i hex()."

Na pytanie dlaczego, odpowiedź musi leżeć w Pythonie 3.0, który wykorzystuje __index__ przeciążać hex(), oct() i bin(), i usunęła funkcji specjalnych __oct__ i __hex__ całkowicie.

Tak więc Python 2.6 bin() wygląda bardzo podobnie do wersji Pythona 3.0, która została przeniesiona z powrotem bez większego zastanowienia, że ​​robi to w nowy sposób w Pythonie 3, a nie w starym Pythonie 2. Sądzę też, że jest mało prawdopodobne, aby naprawić, nawet jeśli jest to błąd.

1

Funkcja bin odbiera wartość z funkcji obiektu __index__. Tak więc dla obiektu można zdefiniować wartość przekonwertowaną na binarną, ale nie można zdefiniować formatu ciągu znaków.

0

Można osiągnąć to samo zachowanie, co w przypadku heksadecymalnie i ósemkowo, zastępując wbudowaną funkcję bin() własną implementacją, która próbowała wywołać bin na obiekcie, który został przekazany i powrócił do standardowego pojemnika (), jeśli obiekt nie zapewniał bin. Jednak na podstawie tego, że jawność jest lepsza niż niejawna, kodowanie aplikacji do wersji niestandardowej bin() prawdopodobnie nie jest dobrym pomysłem, więc może po prostu nadać tej funkcji inną nazwę, np.

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

Jeśli chodzi o przyczyny niespójności interfejsu, nie jestem pewien. Może dlatego, że bin() został dodany niedawno, więc jest to lekki niedopatrzenie?

11

Jak już odkryłeś, nie możesz przesłonić bin(), ale nie brzmi tak, jak musisz to zrobić. Po prostu potrzebujesz wartości binarnej 0-padded. Niestety w pythonie 2.5 i wcześniejszych nie można użyć "% b" do wskazania binarnego, więc nie można użyć operatora formatowania ciągów "%", aby osiągnąć pożądany wynik.

Na szczęście python 2.6 oferuje to, co chcesz, w postaci nowej metody str.format(). Wierzę, że ten konkretny kawałek składzie hałasu jest to, czego szukasz:

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

Składnia tego mini-język jest pod „format specification mini-language” w docs. Aby zaoszczędzić trochę czasu, będę tłumaczyć ciąg znaków, który używam:

  1. parametr zero (tj 19) powinien być sformatowany za pomocą
  2. magiczne „0”, aby wskazać, że chcę 0- wyściełany, wyrównany do prawej numer, z
  3. 10 cyfr precyzji, w
  4. format binarny.

Możesz użyć tej składni, aby uzyskać różne kreatywne wersje wyrównania i dopełnienia.

+0

Dzięki, warto wiedzieć. Jednak udało mi się już uzyskać wynik w żądanej formie, po prostu nie mogłem odzyskać funkcji bin. Twoja metoda str.format jest znacznie bardziej zwięzła niż metoda, której użyłem! –

+0

Zobacz także http://stackoverflow.com/questions/3258330/converting-from-hex-to-binary- bez-wybieranie-leading-s-python – endolith

Powiązane problemy