Python 3 liste avec [b""\n"]
mamiemando Messages postés 33444 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 26 mars 2024 à 11:40
- Python 3 liste avec [b""\n"]
- Liste déroulante excel - Guide
- Liste déroulante en cascade - Guide
- Picasa 3 - Télécharger - Albums photo
- Citizen code python avis - Accueil - Outils
8 réponses
Bonsoir.
Le b indique que c'est un bytes.
Ce qu'on peut voir en affichant le type.
print(type(liste_retour[0]))
Pour transformer en str, il faut se servir de la méthode decode de bytes.
Et pour le \n de fin, bah avec str.strip, str.rstrip.
Modifié le 23 mars 2024 à 20:41
bonsoir,
Pourtant quand j'utilise décode()
retour_decode = str(m).decode('utf-8') print(type("retour_decode : ",retour_decode))
retour
File "/home/laurent/Langages/python/3.4.3/Gestion-des-utilisateurs-et-groupes/Gdueg-02.py", line 936, in valider_fenetre_supprimer_le_repertoire_personnel_d_un_utilisateur retour_decode = str(m).decode('utf-8') AttributeError: 'str' object has no attribute 'decode'
et avec
print ("type(m) : ",type(m)) retour_decode = bytes(m, 'utf-8') print("type(retour_decode) : ",type(retour_decode)) print("retour_decode : ",retour_decode)
le retour
type(m) : <class 'str'> type(retour_decode) : <class 'bytes'> retour_decode : b'[b"/usr/bin/rm: impossible de supprimer \'/home/utilisateur\': Aucun fichier ou dossier de ce type\\n"]'
Je tourne en rond, encore ['b' dans la liste.
Merci.
Forcément, tu convertis ton bytes en str, il faut simplement utiliser decode sur le bytes, puisque c'est une méthode de cette classe.
import subprocess process = subprocess.Popen( ['ls', '-alh', '/dev'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) liste_retour = process.stdout.readlines() print(len(liste_retour)) print(type(liste_retour[-1])) print(liste_retour[-1].decode()) # str
Qui par ex. me retourne
188 <class 'bytes'> crw-rw-rw- 1 root root 1, 5 mars 21 19:27 zero
Modifié le 26 mars 2024 à 11:21
Re,
Je ne comprends pas avec
print () import subprocess process = subprocess.Popen([e1, e2, e3, e4], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) liste_retour = process.stdout.readlines() print ("liste_retour : ",liste_retour) if not liste_retour: print ("Im an error") err = process.stderr.readlines() print('ERROR: {}'.format(err)) liste_retour = [] #liste_retour.append('ERROR:{}'.format(err)) liste_retour.append(format(err)) print("liste_retour : ",liste_retour) print("len(liste_retour) : ",len(liste_retour)) print () print("type(liste_retour) : ",type(liste_retour)) #print("liste_retour.decode() : ",liste_retour.decode()) # str print () print("type(liste_retour[-1]) : ",type(liste_retour[-1])) print("liste_retour[-1].decode() : ",liste_retour[-1].decode()) # str else: print ("I'm a success") print("liste_retour : ",liste_retour)
retour :
File "/home/laurent/Langages/python/3.4.3/Gestion-des-utilisateurs-et-groupes/Gdueg-02.py", line 1008, in valider_fenetre_supprimer_le_repertoire_personnel_d_un_utilisateur print("liste_retour[-1].decode() : ",liste_retour[-1].decode()) # str AttributeError: 'str' object has no attribute 'decode
idem avec liste_retour.decode()
Y a un problème avec decode ?
Merci.
24 mars 2024 à 15:47
decode() fonctionne bien.
import subprocess process = subprocess.Popen("kmd 'dyr' -c", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) liste_retour = process.stdout.readlines() if not liste_retour: err = process.stderr.readlines() liste_retour=[] for l in err: liste_retour.append(l.decode()) for retour in liste_retour: print("+", retour)
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionBonjour,
et ça, ça affiche quoi :
print("type(liste_retour[-1]) : ",type(liste_retour[-1]))
est-ce que ça affiche
<class 'bytes'> comme ça le devrait ????
Salut.
Le code que je t'ai mis n'est pas à utiliser au cas où il y a une erreur.
Mais c'est de toute façon la même chose, je ne comprends pas ce que tu fais.
Ton code si tu veux ajouter l'erreur à la liste devrait se résumer à :
import subprocess process = subprocess.Popen(['ls', 'hih'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) liste_retour = process.stdout.readlines() if not liste_retour: err = process.stderr.readlines() print('err', type(err), len(err), type(err[0])) # err <class 'list'> 1 <class 'bytes'> liste_retour.append(f'ERROR: {err[0].decode().rstrip()}') print("liste_retour : ", liste_retour) else: print ("I'm a success") print("liste_retour : ", liste_retour)
Qui donc afficherait : liste_retour : ["ERROR: ls: impossible d'accéder à 'hih': Aucun fichier ou dossier de ce type"]
Je pense que tu cherches compliqué, alors que c'est très simple ^^
Modifié le 26 mars 2024 à 11:21
bonjour,
err = process.stderr.readlines() m = "" for l in err: m += l.decode() print(m)
Modifié le 26 mars 2024 à 11:50
Bonjour
Quelques explications préalables
subprocess n'a pas d'a priori sur la nature des caractères retournés par un processus, et voit donc le flux retourné comme une suite d'octet. Il y a une raison technique à ça : certaines commandes retourne un flux binaire, pas un flux texte. Il t'appartient donc de reconvertir ce flux en caractère si le besoin s'en fait sentir.
Tant qu'on est dans l'encodage, si tu te demandes lequel utiliser, je te recommande d'utiliser partout et autant que possible de l'UTF-8 dans toutes les situations (c'est ce qui est fait de nos jours par défaut sous Linux et c'est un bon choix).
Concernant l'appel à un sous-processus, il faut vérifier s'il est en erreur ou pas pour savoir s'il s'est bien déroulé ou non. Par convention, un programme qui se termine bien retourne 0, une valeur non nulle sinon. En shell tu peux vérifier le code de retour de la dernière commande en affichant la valeur de $?.
Exemple :
cat /etc/fstab > /dev/null; echo $? # Fonctionne, affiche 0 cat /etc/shadow > /dev/null; echo $? # Échoue, affiche 1
De plus, un processus affiche ses résultats dans deux flux (soit stdout, soit stderr) ce qui correspond en shell aux redirections :
- 1>, 1>> (ou en abrégé : > et >>) pour stdout
- 2>, 2>> pour stderr
Cela signifie que quand tu appelles un sous processus, tu dois potentiellement rattraper ces deux flux.
Retour à python
Voici comment appeler un processus en python
from subprocess import Popen, PIPE def run( cmd: list, stdin_data: bytes | None = None, decode: bool = True, encoding: str = "UTF-8" ) -> bytes | str: """ Run a shell command. Args: cmd (list): The words involved in the shell command. stdin_data (bytes | None): Data passed to the command from ``stdin``. decode (bool): Pass ``True`` to encode the data passed to the subprocess and to decode the data received from the subprocess. encoding (str | None): Encoding used to decode the bytes. """ proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) (stdout_data, stderr_data) = proc.communicate( stdin_data.encode(encoding) if stdin_data else None ) status = proc.wait() if status == 0: if decode: return stdout_data.decode(encoding) else: return stdout_data else: raise RuntimeError( f"{' '.join(cmd)} exit code: {status}\n" "[==== stderr ====]\n" f"{stderr_data.decode(encoding)}\n" ) # ls -la / ls = run(["ls", "-la", "/"]) print(ls) # ... | grep root grep = run(["grep", "root"], stdin_data=ls) print(grep) # cat /etc/shadow cat = run(["cat", "/etc/shadow"]) # Raise RuntimeError
Bonne chance