2009-03-02 9 views
31

Mam ciąg znaków, który może być liczbą heksadecymalną z prefiksem "0x" lub liczbą dziesiętną bez specjalnego prefiksu z wyjątkiem prawdopodobnie znaku minus. "0x123" znajduje się w bazie 16, a "-298" w bazie 10.jak parsować szesnastkowy lub dziesiętny int w Pythonie

Jak przekonwertować to na int lub długie w Pythonie?

Nie chcę używać eval(), ponieważ jest niebezpieczne i przesadne.

+0

Dlaczego eval jest niebezpieczne? Czy źli ludzie będą wymyślać te cyfry? Kto ma dostęp do tych ciągów? Czy są niegodne zaufania? –

+9

eval jest niebezpieczne, ponieważ pozwala na wykonanie dowolnego kodu. Jeśli otrzymujesz ciąg z zaufanego źródła, wciąż jest niebezpieczny, tak się składa, że ​​polegasz na tym zaufanym źródle, aby nie skorzystać z tego. Jeśli zawsze kontrolujesz ciąg znaków, dlaczego był to ciąg? –

+0

Twój program python jest dostępny w formie źródłowej - jest to również "kod arbitralny". Po co narysować linię pomiędzy jednym zestawem źródeł Pythona a innym? Eval jest nie mniej bezpieczny niż uruchamianie programu Python. –

Odpowiedz

52
int("0x123", 0) 

(dlaczego nie int("0x123") zrobić?)

+9

To jest po prostu sposób, w jaki int jest zaimplementowany w Pythonie - przyjmuje wartość dziesiętną, chyba że wyraźnie powiesz mu, że zgadujesz, przekazując 0 jako podstawę. –

+2

Dobrze, więc początkowe zera nie domyślnie określają go jako oś. 'int (" 010 ")' zwraca '10'. –

+0

Ale Python nie reprezentuje liczb ósemkowych z początkowym zerem, powinny one mieć przedrostek '0o' (np.' 0o10'). Jednak najczęściej używanym przypadkiem jest konwersja z liczb dziesiętnych, co jest domyślnym zachowaniem. –

5

Coś jak to może być to, czego szukasz.

def convert(aString): 
    if aString.startswith("0x") or aString.startswith("0X"): 
     return int(aString,16) 
    elif aString.startswith("0"): 
     return int(aString,8) 
    else: 
     return int(aString) 
+0

Dlaczego nie używać 'if aString.upper(). Startswith ('0X'):' W ten sposób nie potrzebujesz ani? oczywiście działa również 'lower()' z ''0x''. – a2j

+0

@ a2j: Nie ma wielkiego powodu. Możesz jednak użyć 'timeit', aby dowiedzieć się, jakie są kompromisy. –

25

bazowa 16 do 10 (powrót liczbę całkowitą):

>>> int('0x123', 16) 
291 

bazowa 10 do 16 (zwraca ciąg znaków):

>>> hex(291) 
'0x123' 
-2

Jest to prostsza wersja, która działa jak urok. Zwraca ciąg od hex() zwraca ten sam typ:

def itoh(int): return hex(int)[2:] 
+1

OP chce przekonwertować ciąg na int. Twój kod idzie w drugą stronę. –

+0

Cunfusing co najmniej jako słowo kluczowe Pythona jako nazwa parametru –

0

Jeśli robisz dużo przejść między różnymi systemami z numerów, biblioteka łańcuch bitów zrobić dużo operacji binarnych/Hex łatwiejsze. Obsługuje również interpretację ciągów znaków:

http://pythonhosted.org/bitstring/

Powiązane problemy