Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 28/03/2019, à 09:37

rin67630

[résolu]Python: comment réaliser une port série virtuel? biblioth pty.

bonjour,
je désire réaliser une interface entre un programme python est un réseau de mesures.
le réseau de mesures attend de recevoir sur une liaison série 1 octet chaque seconde.
je voudrais simuler cette liaison série.

Je pense utiliser pour cela la bibliothèque pty  pour créer un port série virtuel.
j'ai fini par comprendre qu'il n'était pas possible de simplement créer un port série, d'écrire dedans et de pouvoir l'utiliser dans l'application, mais que la bibliothèque créer systématiquement une paire de ports et il faut écrire dans le port esclave (sortie série) lequel transmet les informations au port maître ( entrée série) lequel devrait être pouvoir lu par l'application. En théorie.
La bibliothèque ne permet apparemment par de choisir les noms des ports concernés.
J'ai donc écrit le programme suivant pour être informé des ports utilisés:

#!/usr/bin/python3
 
# requires PySerial: $python -m pip install pyserial

import os, pty, serial
import time
from serial import Serial

master,slave = pty.openpty() #open the pseudoterminal pair
s_name = os.ttyname(slave)   #translate the slave fd to a filename
m_name = os.ttyname(master)  #translate the slave fd to a filename

print ("Slave name is: " , s_name, " | Slave FD is: " , slave)
print ("Master name is: ", m_name, " | Master FD is: " , master)

ser = Serial(s_name, 9600, timeout=2)

while True:
  ser.write(b'test\r\n') #write the first command
  time.sleep(0.99)

la réponse de l'application est la suivante:

~ $ python3 test_pty.py
Slave name is:  /dev/pts/2  | Slave FD is:  4
Master name is:  /dev/ptmx  | Master FD is:  3

Je devrais donc espérer recevoir le message "test" chaque seconde sur le port /dev/ptmx.
Mais ça ne marche pas.

si j'ouvre une application minicom sur le port /dev/ptmx je ne reçois rien.

Quelqu'un peut-il m'expliquer ce que j'ai fait de travers ?

Merci d'avance
Laszlo

Dernière modification par rin67630 (Le 28/03/2019, à 23:01)

Hors ligne

#2 Le 28/03/2019, à 12:22

kholo

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

salut,
je ne suis pas un 'pro' mais je me suis penché sur ton histoire
tu as déjà dû te documenter mais je met un peu de lecture...
pyserial simulator ici
là, sur le forum, utilisation de pyserial
sur framboise, le rasp étant spécialisé pour ça peut te donner de bonnes indications
idem quand on touche à arduino

... et la doc de python voire ici,...

de mon côté, si j'ai tout compris, l'écriture sur port série se comporte comme une écriture de fichier... voire de connecter deux terminaux.
là, tu donnes le code de la fonction d'écriture mais tu devrais bosser sur un script de lecture plutôt que minicom pour créer une paire maîtrisée...
pour faire avancer le truc ici tu as une paire qui fonctionne avec minicom
deux ensembles de codes sont donnés producer et consumer chacun révisés je remet ici les premiers avec les print corrigés
et quelques modifs pour y voir plus clair :

producer.py

import os, sys
from time import sleep

master_fd, slave_fd = os.openpty()
print("master_fd, slave_fd", master_fd, slave_fd)
print("minicom -D %s" % os.ttyname( slave_fd ))

for i in range(0,30): 
    d = str(i % 10)
    ## b = mystring.encode('utf-8')
    # os.write( str(master_fd).encode('utf-8'), d )
    # os.write( master_fd, d )
    os.write( master_fd, b'test\r\n')

    sys.stdout.write( d )
    sys.stdout.flush()
    sleep( 2 )
os.close( slave_fd )
os.close( master_fd )

print("\nDone") 

consumer.py

import os, sys
from time import sleep
# pts=raw_input("Enter pts number:")
pts=int(input("Enter pts number:"))

while True:
    fd=0
    try:
        fd=os.open('/dev/pts/%d' % (pts,), 
            os.O_RDONLY | os.O_NONBLOCK )
        sys.stdout.write( os.read(fd, 1 ) )  
        sys.stdout.flush()
    except Exception as e: print("problème", e)
    if fd: os.close(fd)    
    sleep(1)

tu lances producer qui va te donner le num de pty puis consumer qui va te demander ce nombre pour se connecter...
il reste un truc que je pige pas producer doit envoyer du bytes sinon il refuse et consumer s'attend à récupérer du strings
donc les réponses de consumer tombe dans le except du try !

des exemples ici on voit pas mal d'utilisation de subprocess pour relâcher le système...
le write à l'air différent aussi comme montré ici

... peut être ce script t'as servi de référence voire celui là

en tout cas tout cela m'intéresse et je j'attends d'autres propositions !

edit :
consumer avait un problème que j'ai commencé à trouver :

        sys.stdout.write( str(os.read(fd, 1 )) )  

mais cela me sort lettre par lettre donc à revoir mais ça marche !

Dernière modification par kholo (Le 28/03/2019, à 13:07)

Hors ligne

#3 Le 28/03/2019, à 13:59

kholo

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

cool cool
tu peux modifier ton premier message et ajouter [résolu] dans le titre
du coup je met du code fonctionnel pour les prochains :
producer.py

import os, sys
from time import sleep

master_fd, slave_fd = os.openpty()
# print("master_fd, slave_fd", master_fd, slave_fd)
# print("minicom -D %s" % os.ttyname( slave_fd ))
print("port à renseigner :", os.ttyname( slave_fd ).split('/')[-1])


def version1():
    for i in range(0,30):
        d = str(i % 10)
        ## b = mystring.encode('utf-8')
        # os.write( str(master_fd).encode('utf-8'), d )
        # os.write( master_fd, d )
        os.write( master_fd, b'test\r\n')

        sys.stdout.write( d )
        sys.stdout.flush()
        sleep( 2 )
def version2():
    du_texte = "un texte d'exemple"
    for i in range(0,len(du_texte)):
        b = (du_texte + '\r\n').encode('utf-8')
        # os.write( master_fd, b )
        # os.write( master_fd, b"un texte d'exemple\r\n" )
        os.write( master_fd, b )
        sys.stdout.write( str(i) + ' =>' + du_texte[i] + '\n' )
        sys.stdout.flush()
        sleep( 2 )

def version3():
    du_texte = "0"
    while True:
        b = (du_texte + '\r').encode('utf-8')
        os.write( master_fd, b )
        sleep( 1 )

## adapter ici pour changer de version
version3()


os.close( slave_fd )
os.close( master_fd )

print("\nDone")

consumer.py

import os, sys
from time import sleep
# pts=raw_input("Enter pts number:")
pts=int(input("Enter pts number:"))

while True:
    fd=0
    try:
        fd=os.open('/dev/pts/%d' % (pts,), 
            os.O_RDONLY | os.O_NONBLOCK )
        # sys.stdout.write( os.read(fd, 1 ) )  
        # sys.stdout.write( str(os.read(fd, 1 )) )  
        sys.stdout.write( os.read(fd, 1 ).decode('utf-8') )  
        sys.stdout.flush()
    except Exception as e: 
        print("problème", e)
    if fd: os.close(fd)    
    sleep(0.5) # ou 1 !

Hors ligne

#4 Le 28/03/2019, à 18:06

rin67630

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

kholo a écrit :

cool cool

J'ai un peu avancé mais ca coince toujours.

Si je lance le programme producer.py:

import os, sys
from time import sleep

master_fd, slave_fd = os.openpty()
print("master_fd, slave_fd", master_fd, slave_fd)
print("minicom -D %s" % os.ttyname( slave_fd ))

for i in range(0,30): 
    d = str(i % 10)
    ## b = mystring.encode('utf-8')
    # os.write( str(master_fd).encode('utf-8'), d )
    # os.write( master_fd, d )
    os.write( master_fd, b'test\r\n')

    sys.stdout.write( d )
    sys.stdout.flush()
    sleep( 2 )
os.close( slave_fd )
os.close( master_fd )

print("\nDone") 

il imprime:
minicom -D /dev/pts/3
mais ne démarre pas minicom. En fait il imprime la variable i depuis python, pas depuis minicom.

Avec  minicom -D /dev/pts/3 depuis un autre terminal, il imprime "test" sur 30 lignes. C'est déjà ca!

Il me faut maintenant trouver le moyen d'envoyer un octet de valeur entre 50 et 250 décimal vers minicom -D /dev/pts/3 a chaque seconde..
Si je change  os.write( master_fd, [une variable] ) python râle et veut un string...
l'instruction os.write( str(master_fd).encode('utf-8'), d ) ne fonctionne pas.

Après tout un port série doit pouvoir transporter autre chose que du texte...
Merci.

P.S. par curiosité: pourquoi a-t-on utilisé
        sys.stdout.write( os.read(fd, 1 ).decode('utf-8') ) 
        sys.stdout.flush()
au lieu de print()?

Dernière modification par rin67630 (Le 28/03/2019, à 18:39)

Hors ligne

#5 Le 28/03/2019, à 21:08

kholo

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

j'avoue que j'ai pas mal galérer avec ces histoires de write...
d'abord on pourrait croire que le write envoie caractère par caractère mais c'est pas le cas... enfin pas tout à fait.
si tu regarde ma version2()... je la remet ici nettoyée:

def version2():
    du_texte = "un texte d'exemple"
    for i in range(0,len(du_texte)):
        b = (du_texte + '\r\n').encode('utf-8')
        os.write( master_fd, b )
        sys.stdout.write( str(i) + ' =>' + du_texte[i] + '\n' )
        sys.stdout.flush()
        sleep( 2 )

tu peux voir que je pensais justement que je partais du principe qu'on pouvais prendre un texte et l'envoyer découpé lettre par lettre... sauf que non.
voilà ce qui se passe :
je lance version2

port à renseigner : 6
0 =>u
1 =>n
2 => 
3 =>t
4 =>e
5 =>x
6 =>t
7 =>e
8 => 
9 =>d
10 =>'
11 =>e
12 =>x
13 =>e
14 =>m
15 =>p
16 =>l
17 =>e

Done

qui me dit de me connecter en 6 donc customer en 6
donc je me connecte et il rattrape le flot... des caractère envoyé puis le dépasse roll
puis il arrive à la fin de ma chaîne de caractère et la reprend depuis le début

Enter pts number:6
un texte d'exemple

un texte d'exemple

un texte problème [Errno 2] No such file or directory: '/dev/pts/6'
problème [Errno 2] No such file or directory: '/dev/pts/6'
problème [Errno 2] No such file or directory: '/dev/pts/6'
problème [Errno 2] No such file or directory: '/dev/pts/6'

puis le flot en envoie étant terminé il arrête d'envoyer et coupe donc on passe en

un texte problème [Errno 2] No such file or directory: '/dev/pts/6'

donc ce n'est pas un simple flot qui est envoyé d'un côté et réceptionné de l'autre.

ça t'aide ?

Hors ligne

#6 Le 28/03/2019, à 21:52

rin67630

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

kholo a écrit :

j'avoue que j'ai pas mal galérer avec ces histoires de write...

Et moi alors!...

Maintenant je pense avoir le code...

import os, sys
import usb.core
from time import sleep

master_fd, slave_fd = os.openpty()
print("master_fd, slave_fd", master_fd, slave_fd)
print("minicom -D %s" % os.ttyname( slave_fd ))

for i in range(50,250): 
    d = str( i )
    os.write (master_fd,i.to_bytes(1,byteorder='big'))
    sys.stdout.write( d )
    sys.stdout.flush()
    sleep( 1 )
os.close( slave_fd )
os.close( master_fd )

print("\nDone") 

Celà donne avec minicom

Welcome to minicom 2.7

OPTIONS: I18n 
Compiled on Apr 22 2017, 09:14:19.
Port /dev/pts/3, 20:42:30

Press CTRL-A Z for help on special keys                      
789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv....

Zoli! smile
Avec mon code complet, ca semble marcher aussi...

Maintenant, il va falloir s'attaquer au handshake initial
Il faut aussi ecouter le port  /dev/pts/3 pour un caractère 11, suivi de 1,2 ou 3 et répondre par le même 1,2 ou 3.
Ca devrait être faisable, si l'écoute marche...
Je vous tiens au courant...

Merci de votre aide!

Hors ligne

#7 Le 28/03/2019, à 23:15

rin67630

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

kholo a écrit :

salut,
... et la doc de python voire ici,...
!

Je dois avouer que la doc de Python, c'est du volapük pour moi .

J'ai fini par comprendre a moitié la partie pty.openpty()

Mais en ce qui concerne  pty.fork()¶ et surtout  pty.spawn(argv[, master_read[, stdin_read]])¶ j'y pige que dalle!
L'example n'a rien d'intuitif, pas un commentaire, rien!

C'est clair pour vous?

Hors ligne

#8 Le 29/03/2019, à 10:58

kholo

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

salut,
il est de bon ton de se tutoyer sur le forum... mais tu fais comme tu veux !

regardons write

la doc a écrit :

https://docs.python.org/3.2/library/os.html#os.openpty
os.write(fd, str)
    Write the bytestring in str to file descriptor fd. Return the number of bytes actually written.

    Availability: Unix, Windows.

    Note
    This function is intended for low-level I/O and must be applied to a file descriptor as returned by os.open() or pipe(). To write a “file object” returned by the built-in function open() or by popen() or fdopen(), or sys.stdout or sys.stderr, use its write() method.

pas facile...
si je regarde ton code ici :

for i in range(50,250): 
    d = str( i )
    os.write (master_fd, i.to_bytes(1, byteorder='big'))

je vois que tu continues à tenter de balancer byte par byte les éléments de ton range... tu me suis ?
d'après moi... et c'est là que c'est confus :
quand tu balances une string en entier dans ton write cette string est intégralement envoyée tout au long de ta boucle.
en fait, ta boucle devrait tester un retour sur une autre condition qui serait gérée par consumer et breaker producer lorsque la condition est remplie...
pour les tests on a des envois dans un seul sens et pas de vérification que cela a bien été reçu.

voici un exemple qui va peut être plus t'éclairer :
j'ai changé la valeur du sleep dans la boucle de consumer, c'est plus parlant ! wink
le producer.py

#!/usr/bin/env python3
# -*- coding: UTF8 -*-
import os, sys
# import usb.core
from time import sleep

master_fd, slave_fd = os.openpty()
print("master_fd, slave_fd", master_fd, slave_fd)
# print("minicom -D %s" % os.ttyname( slave_fd ))

def envoie(du_texte):
    """ envoie du texte pendant deux minutes (puisque sleep 1)"""
    for i in range(0,120):
        d = str(i % 10)
        le_texte = du_texte + '\r\n'
        os.write( master_fd, le_texte.encode('utf-8'))
        sys.stdout.write( d )
        sys.stdout.flush()
        sleep( 1 )
du_texte = 'je suis une string'
envoie(du_texte)

os.close( slave_fd )
os.close( master_fd )

print("\nDone")

le consumer.py

#!/usr/bin/env python3
# -*- coding: UTF8 -*-
import os, sys
from time import sleep
pts=int(input("Enter pts number:"))

while True:
    fd=0
    try:
        fd=os.open('/dev/pts/%d' % (pts,), 
            os.O_RDONLY | os.O_NONBLOCK )
 
        sys.stdout.write( os.read(fd, 1 ).decode('utf-8') )
        sys.stdout.flush()
    except Exception as e: 
        pass
        # print("problème", e)
    if fd: os.close(fd)    
    sleep(0.1) # écart entre les boucles de récupération des caractères

de mon côté je lance le consumer en premier et je le laisse en attente sur le input,
puis le producer qui me donne la valeur du pty que je renseigne dans le consumer.

en me relisant une question me taraude...
dans consumer le fd, 1 pour byte par byte ?
qui est ensuite reconstitué dans le stdout write... à voir

pour les write vers stdout à la place des print je pense que ça complique juste un peu plus le code
et que ça reste dans l'esprit des exemples, mais rien n’empêche d'utiliser les deux
... et c'est peut être "plus simple" pour la gestion des sauts de ligne

Hors ligne

#9 Le 29/03/2019, à 13:07

rin67630

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

Bonjour,

je ne vovoyais pas, je m'addressais à tout le monde sur le forum smile

> je vois que tu continues à tenter de balancer byte par byte les éléments de ton range.

Oui, c'est comme ca que l'appli de l'autre côté attend de recevoir le signal par liaison série. Un byte chaque seconde...
Il n'y a pas de boucle en Python. Il n'y a que l'emetteur. Le recepteur est une appli closed source dont je peux seulement configurer le port d'entrée.

Celà dit, pour ne pas mourir idiot: tu comprends la doc de la bibliothèque pty?
- pty.fork()
- pty.spawn(argv[, master_read[, stdin_read]])
C'est censé faire quoi en francais de monsieur tout le monde?

Hors ligne

#10 Le 29/03/2019, à 17:32

kholo

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

on est loin d'être les premiers à chercher...
les explications sur stackoverflow semblent complète
un des posts renvoie vers des explications et exemples :
about pty's and tty's et a link to a simple example of using pty.fork().
qu'est ce qu'un terminal : un émulateur de console qui n'est qu'une IHM...
donc, en python, au lieu d'intercepter des lignes d'un terminal puis les parser comme on le fait en bash par exemple, on peut remonter le process en créant un pseudo terminal et envoyer et recevoir des infos pour les traiter en pure python sans utiliser exec ou eval (qui peuvent facilement devenir des trous béants de sécurité).
enfin, si j'ai bien tout compris...

je ne comprend pas cette affirmation :

rin67630 a écrit :

Il n'y a pas de boucle en Python

je me doute que tu ne parles pas d'une vue généraliste mais là il faut bien créer une boucle autant pour envoyer des infos que pour voir si elles ont bien été reçues voire les renvoyer si elles ont mal été reçues.
Par exemple, l'écriture sur un medium (hdd, fd, zip, bande,...) est souvent problématique, donc les données écrites sont relues et comparées avec les données qui devraient y être pour être éventuellement ré-écrites... puis re-testées.

pour pty.spawn j'ai d'abord vu que spawn se traduit par frayer (ou peut être "se frayer") comme se frayer un chemin.
cette ligne vu ici semble expliquer son utilisation :

python -c import pty;pty.spawn("bash")

j'avoue que comprendre les tenants et aboutissants me fait bien chauffer le cerveau
pour moi qui ne suis qu'un autodidacte et ni white, ni black hate, ce genre de jonglage me pousse dans mes retranchements !
bref, l'utilisation semble être de créer un bac à sable, de cloisonner une exécution, voire émuler un shell pour test... ou hack, si j'ai tout compris.

Bon, et de ton côté comment ça avance ?
ton appli fermée elle s'attend à avoir quoi comme type d'infos ?
on pourrait peut être faire du reverse enge et créer autrement les instructions qui la font vibrer !
... wè, en même temps c'était ça ton code du début :

ser = Serial(s_name, 9600, timeout=2)

while True:
  ser.write(b'test\r\n') #write the first command
  time.sleep(0.99)

bon, je te laisse digérer mes infos et je continue d'y cogiter...

t'as une idée de ce que je pourrais prendre pour créer un environnement réaliste de test ?

Hors ligne

#11 Le 29/03/2019, à 19:20

rin67630

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

kholo a écrit :

on est loin d'être les premiers à chercher...
les explications sur stackoverflow semblent complète
un des posts renvoie vers des explications et exemples :
about pty's and tty's et a link to a simple example of using pty.fork().

Merci, je vais essayer de comprendre...

kholo a écrit :

pour pty.spawn j'ai d'abord vu que spawn se traduit par frayer (ou peut être "se frayer") comme se frayer un chemin.

Je pense plutôt à frayer aus sens de se reproduire comme les saumons...

kholo a écrit :

Bon, et de ton côté comment ça avance ?
ton appli fermée elle s'attend à avoir quoi comme type d'infos ?

La sortie pseudo tty marche comme il faut.
Il me manque le handshake du début. Pas trop compliqué, mais il me faudra plonger dans la lecture d'octets depuis le port virtuel.
Python n'est vraiment pas pratique pour le traitement par octets...
En attendant, comme je ne peux pas garantir le /dev/pty/[n] utilisé (qui es arbitrairment décidé par la bibliothèque), je vais m'arranger pour que mon programme Python modifie le fichier de config de l'appli à la volée et la démarre ensuite...

Le but est d'utiliser un sonomètre à 25€ et lui faire envoyer ses données au programme convertisseur réseau comme s'il venaient de la liaison série de stations acoustiques pro à 45 000€ chaque!
Ces stations utilisent un protocole datant des années 60. Comme on a un réseau de plusieurs milliers de stations, rien n'est prêt de changer.

kholo a écrit :

t'as une idée de ce que je pourrais prendre pour créer un environnement réaliste de test ?

En fait à part tester tous les caractères et les faire lire par une autre appli, je vois pas trop ce qui peut se passer...

Bon week-end!

Hors ligne

#12 Le 30/03/2019, à 06:15

kholo

Re : [résolu]Python: comment réaliser une port série virtuel? biblioth pty.

...
sonomètre, stations, plusieurs milliers, années 60...
météo ? ... données SYNOP ?
si c'est le cas ce n'est pas seulement un système de triggers mais une mesure cyclique de la pression qui est envoyée... ?

rin67630 a écrit :

En attendant, comme je ne peux pas garantir le /dev/pty/[n]

ça, faut voir avec la bibliothèque. tu peux peut être la forker au niveau python ou par un programmeur C (là, j'ai pas les compétences... et sans doute même pas en pyton lol ). Tu parles de milliers de stations ça peut valoir le coup d'avoir un programme spécifique et open !

rin67630 a écrit :

Python n'est vraiment pas pratique pour le traitement par octets

octet par octet dis tu ?

# source file for reading (r)b
src = open("history.dat", "rb")
 
# destination file for writing (w)b
dst = open("adjusted.dat", "wb")
# source file to read an modify (r+)b
f = open("history.dat", "r+b")
 

et avec python3 ya bytearray() mais pas encore eu l'occasion de tester

la page a écrit :
>>> s = bytearray(b"this tasted purple !")
>>> s[2:4] = b'at'
>>> print(s)
bytearray(b'that tasted purple !')

Et on a toutes les opérations de liste dessus, comme append, pop(), etc :

>>> for x in b' ,puY':
...     s.insert(0, x)
... 
>>> print(s)
bytearray(b'Yup, that tasted purple !')

et NB, à part qu'il a oublié le correcteur orthographique,

SAM a écrit :

En Python, quand on récupère un bout de strings, on récupère une string plus petite. Bref, pour faciliter la vie des devs, s[0] ne donne pas une partie de s, mais une nouvelle séquence, de longueur 1.

Comme les bytes sont beaucoup plus bas niveau, les bytes n’ont pas ce traitement magique, et récupérer un bout du type bytes() donne bien un seul des éléments qui compose ce flux d’octets. Un octest, c’est un nombre, donc c’est logique que ce soit un int.

Attention, il N’Y A AUCUNE LETTRE dans les bytes.

Je sais les gens ont une forte tendance à confondre ce qui s’affiche dans le shell avec les données elles-mêmes.

Par exemple:

>>> bytes([115, 97, 109])
    b'sam'

Là on a une instruction qui dit : “créer un flux de données qui contient 3 octests. Je fournis ces valeurs sous la forme d’entiers, créés à partir d’une notation en base 10.

Le shell me répond: “voilà, j’ai créé ton flux de donnée. je t’affiche une réprésentation de ce flux sous forme de caractères ascii”.

La donnée n’est pas différent en entrée et en sortie. J’ai juste une réprésentation différente à la saisie et à l’affichage.

Exemple, je fais:

>>> bytes((0x73, 0x61, 0x6d))
    b'sam'

Là on a AUSSI une instruction qui dit : “créer un flux de données qui contient 3 octests . Je fournis ces valeurs sous la forme d’entiers”. Mais j’ai créés ces entiers à partir d’une notation en base 10.

Ensuite:

>>> b'sam'
    b'sam'

Là on a AUSSI une instruction qui dit : “créer un flux de données qui contient 3 octests . Je fournis ces valeurs sous la forme d’entiers”. Mais j’ai créés ces entiers à partir d’une notation en base ASCII.

Et c’est la la truc : dans le monde du bas niveau, on manipule des octets (des bytes), donc des nombres, avec des représentations différentes. Par exemple avec des lettres ASCII. Mais c’est le même nombre.

Par ailleurs, un autre difficulté et que la notation pour créer une lettre est très similaire à celle utilisée pour créer un octet:

>>> 'a'
    'a'
>>> b'a'
    b'a'

Mais cest instruction ne font pas DU TOUT la même chose. L’un créé un type destiné à être manipulé comme des lettres. L’autre créé un type destiné à être manipulé comme une sequence de chiffres.

Donc, au contraire, le type bytes est TRES explicite, et force les programmeurs à clairement délimiter les cas où ils manipules des données qui sont conceptuellement des octets bas niveau, celles qui sont conceptuellement du texte.

Je dis conceptuellement, car évidement, au niveau de l’implémentation, le texte est représenté par des octets. Mais quand on manipule du texte, on est pas intéressé par sa valeur en tant qu’octet. On veut l’afficher. Le splitter. Le mettre en majuscule.

Quand on manipule des bytes, on est intéressé par la valeur des octets.

Alors vient une difficulté supplémentaire: comment afficher les bytes qu’on a manipulé. Et bien il faut le concertir explictement en type str. Car cela oblige à penser à l’encoding et à l’échappement, une grosse source de bug qui pose problèmes à tout ceux qui manipulent bytes et textes sont faire attention.

bon, j'arrête,... quand un truc me passionne j'prends la tête à tout l'monde lol
bon WE à toi également !

Hors ligne