web-dev-qa-db-fra.com

python ValueError: littéral invalide pour float ()

J'ai un script qui lit les données de température:

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)

Parfois, le script échoue sur la ligne qui convertit les valeurs en float:

Fichier "./projector.py", ligne 129, dans get_temp
data [ch] = float (temp)
ValueError: Littéral invalide pour float (): + 135.057E + 0
+ 078.260E + 0
+00029

mais ce n'est pas un littéral invalide. Si j'entre ceci dans n'importe quel shell python,

float(+135.057E+0)

alors il retourne correctement 135.057.

Alors quel est le problème?

21
astronomerdave

Je voudrais presque garantir que le problème est une sorte de caractère non imprimable qui est présent dans la valeur que vous avez retirée de votre socket. On dirait que vous utilisez Python 2.x, auquel cas vous pouvez les vérifier avec ceci:

print repr(temp)

Vous y verrez probablement quelque chose d'échappé sous la forme \x00. Ces caractères non imprimables ne s'affichent pas lorsque vous imprimez directement sur la console, mais leur présence est suffisante pour avoir un impact négatif sur l'analyse d'une valeur de chaîne dans un float.

- Edité pour les changements de question - 

Il s'avère que cela est en partie exact pour votre problème - la cause première semble toutefois être que vous lisez plus d'informations que ce que vous attendez de votre socket ou que vous recevez plusieurs valeurs. Vous pourriez faire quelque chose comme 

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

Afin de convertir chacune des valeurs, mais si votre fonction est supposée renvoyer une seule valeur de type float, cela risque de créer une confusion. Quoi qu'il en soit, le problème tourne certainement autour de la présence de caractères que vous ne vous attendiez pas à voir dans la valeur extraite de votre socket.

11
g.d.d.c

Méfiez-vous des littéraux non voulus dans votre argument

par exemple, vous pouvez avoir un espace dans votre argument, le rendant en chaîne/littéral:

float(' 0.33')

Après m'être assuré que l'espace inattendu ne figurait pas dans l'argument, il me restait avec:

float(0.33) 

Comme ça, ça marche comme un charme. 

Take away is: Portez une attention particulière aux littéraux non voulus (par exemple, des espaces que vous n'avez pas vus) dans votre entrée.

0
mrk

J'ai eu un problème similaire en lisant la sortie série d'une balance numérique. Je lisais [3:12] sur une chaîne de sortie de 18 caractères.

Dans mon cas, il y a parfois un caractère nul "\ x00" (NUL) qui apparaît comme par magie dans la chaîne de réponse de la balance et n'est pas imprimé. 

Je recevais l'erreur:

> '     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

Après quelques recherches, j'ai écrit quelques lignes de code qui fonctionnent dans mon cas.

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)

Les réponses dans ces messages ont aidé:

  1. Comment se débarrasser de\x00 dans mon tableau d'octets?
  2. Littéral non valide pour float (): 0.000001, comment corriger l'erreur?
0
parovelb