python ValueError: ongeldige letterlijke waarde voor float()

Ik heb een script dat temperatuurgegevens leest:

def get_temp(socket, channels):
    data = {}
    for ch in channels:
        socket.sendall('KRDG? %s\n' % ch)
        time.sleep(0.2)
        temp = socket.recv(32).rstrip('\r\n')
        data[ch] = float(temp)

Soms mislukt het script op de regel die de waarden naar float converteert:

Bestand “./projector.py”, regel 129, in get_temp
data[ch] = float(temp)
ValueError: ongeldige letterlijke waarde voor float(): +135.057E+0
+078.260E+0
+00029

maar dit is GEEN ongeldige letterlijke. Als ik dit in een python-shell invoer,

float(+135.057E+0)

dan geeft het correct 135.057 terug.

Dus wat is het probleem?


Antwoord 1, autoriteit 100%

Ik zou bijna garanderen dat het probleem een soort niet-afdrukbaar karakter is dat aanwezig is in de waarde die je uit je socket hebt gehaald. Het lijkt erop dat je Python 2.x gebruikt, in welk geval je ze als volgt kunt controleren:

print repr(temp)

Waarschijnlijk zie je daar iets met escapetekens in de vorm \x00. Deze niet-afdrukbare tekens worden niet weergegeven wanneer u rechtstreeks naar de console afdrukt, maar hun aanwezigheid is voldoende om het ontleden van een tekenreekswaarde in een float negatief te beïnvloeden.

— Bewerkt voor vraagwijzigingen —

Het blijkt dat dit gedeeltelijk klopt voor uw probleem – de hoofdoorzaak lijkt echter te zijn dat u meer informatie leest dan u van uw socket verwacht of anderszins meerdere waarden ontvangt. Je zou iets kunnen doen als

map(float, temp.strip().split('\r\n'))

Om elk van de waarden te converteren, maar als uw functie een enkele float-waarde zou moeten retourneren, zal dit waarschijnlijk verwarring veroorzaken. Hoe dan ook, het probleem draait zeker om de aanwezigheid van tekens die je niet had verwacht te zien in de waarde die je uit je socket hebt gehaald.


Antwoord 2

Ik had een soortgelijk probleem bij het lezen van de seriële uitvoer van een digitale weegschaal. Ik las [3:12] uit een uitvoerreeks van 18 tekens.

In mijn geval is er soms een null-teken “\x00” (NUL) dat op magische wijze in de antwoordreeks van de schaal verschijnt en niet wordt afgedrukt.

Ik kreeg de foutmelding:

> '     0.00'
> 3 0 fast loop, delta =  10.0 weight =  0.0 
> '     0.00'
> 1 800 fast loop, delta = 10.0 weight =  0.0 
> '     0.00'
> 6 0 fast loop, delta =  10.0 weight =  0.0
> '     0\x00.0' 
> Traceback (most recent call last):
>   File "measure_weight_speed.py", line 172, in start
>     valueScale = float(answer_string) 
>     ValueError: invalid literal for float(): 0

Na wat onderzoek heb ik een paar regels code geschreven die in mijn geval werken.

replyScale = scale_port.read(18)
answer = replyScale[3:12]
answer_decode = answer.replace("\x00", "")
answer_strip = str(answer_decode.strip())
print(repr(answer_strip))
valueScale = float(answer_strip)

De antwoorden in deze berichten hebben geholpen:

  1. Hoe zich te ontdoen van \x00 in mijn array van bytes?
  2. Ongeldige letterlijke waarde voor float(): 0.000001, hoe een fout op te lossen?

Antwoord 3

Pas op voor mogelijke onbedoelde letterlijke termen in uw argument

u kunt bijvoorbeeld een spatie in uw argument hebben, waardoor het wordt omgezet in een tekenreeks / letterlijk:

float(' 0.33')

Na er zeker van te zijn dat de onbedoelde spatie niet in het argument terechtkwam, bleef ik achter met:

float(0.33) 

Zo werkt het als een tierelier.

Afhalen is:
Let op voor onbedoelde letterlijke waarden (bijv. spaties die u niet zag) in uw invoer.

Other episodes