Domanda Cos'è un test di Python?


Cos'è un test di Python?

Tutto quello che posso trovare sono argomenti su come codificare per eseguire o decodificare ascii o utf-8. Sto cercando di capire come funziona sotto il cofano. In una normale stringa ASCII, è una matrice o un elenco di caratteri e ogni carattere rappresenta un valore ASCII compreso tra 0 e 255, quindi è così che si sa quale carattere è rappresentato dal numero. In Unicode, è la rappresentazione a 8 o 16 byte per il personaggio che ti dice quale carattere è.

Quindi cos'è un test? In che modo Python sa quali personaggi rappresentare come cosa? Come funziona sotto il cofano? Dal momento che puoi stampare o anche restituire queste stringhe e ti mostra la rappresentazione della stringa, non riesco a capirlo ...

Ok, quindi il mio punto è decisamente mi stai perdendo qui. Mi è stato detto che è un immutabile sequenza di byte senza alcun particolare interpretazione.

Una sequenza di byte .. Va bene, diciamo un byte:
'a'.encode() ritorna b'a'.

Abbastanza semplice Perché posso leggere il un?

Diciamo che ottengo il valore ASCII per un, facendo questo:
printf "%d" "'a"

Ritorna 97. Ok, bene, il valore intero per il carattere ASCII un. Se interpretiamo 97 come ASCII, dite in un C char, quindi prendiamo la lettera a. Giusto. Se convertiamo la rappresentazione in byte in bit, otteniamo questo:

01100001

2 ^ 0 + 2 ^ 5 + 2 ^ 6 = 97. Freddo.

Quindi, perché è 'a'.encode() ritorno b'a' invece di 01100001??
Se è senza un particolare interpretazione, non dovrebbe restituire qualcosa del genere b'01100001'?
esso sembra come se lo interpretasse come ASCII.

Qualcuno ha detto che sta chiamando __repr__ sul bytestring, quindi è visualizzato in forma leggibile. Tuttavia, anche se faccio qualcosa come:

with open('testbytestring.txt', 'wb') as f:
    f.write(b'helloworld')

Lo farà ancora inserire helloworld come una normale stringa nel file, non come una sequenza di byte ... Quindi è un bytestring in ASCII?


26
2018-04-02 22:45


origine


risposte:


Pitone non sapere come rappresentare un bytestring. Questo è il punto.

Quando si emette un carattere con valore 97 in quasi tutte le finestre di output, si otterrà il carattere 'a' ma questo non fa parte dell'implementazione; è solo una cosa che è localmente vera. Se si desidera una codifica, non si usa la stringa di testo. Se usi la funzione di test, non hai una codifica.

Il tuo pezzo sui file .txt mostra che hai frainteso ciò che sta accadendo. Vedete, anche i file di testo non hanno una codifica. Sono solo una serie di byte. Questi byte vengono tradotti in lettere dall'editor di testo, ma non vi è alcuna garanzia affatto che qualcun altro che apre il tuo file vedrà la tua stessa cosa se ti allontani dal set comune di caratteri ASCII.


15
2018-04-03 07:49



È un comune malinteso che il testo sia ascii o utf8 o cp1252, e quindi i byte sono testo.

Il testo è solo testo, nel senso che le immagini sono solo immagini. La questione di archiviare testo o immagini su disco è questione di codificare quei dati in una sequenza di byte. Esistono molti modi per codificare le immagini in byte: Jpeg, png, svg e allo stesso modo molti modi per codificare testo, ascii, utf8 o cp1252.

Una volta che la codifica è avvenuta, i byte sono solo byte. I byte non sono più immagini, hanno dimenticato i colori che intendono; sebbene un decodificatore di formato immagine possa recuperare tali informazioni. I byte hanno anche dimenticato le lettere che erano in precedenza. In effetti, i byte non si ricordano affatto di essere immagini o testo. Solo la conoscenza fuori banda (nome file, intestazioni multimediali, eccetera) può indovinare cosa significhino quei byte, e anche quello può essere sbagliato (in caso di corruzione dei dati)

quindi, in python (py3), abbiamo due tipi per cose che potrebbero altrimenti sembrare simili; Per il testo, abbiamo str, che sa che è un testo; sa quali lettere dovrebbe significare. Non sa quali byte potrebbe essere, poiché le lettere non sono byte. Abbiamo anche bytestring, che non sa se si tratta di testo o immagini o qualsiasi altro tipo di dati.

I due tipi sono superficialmente simili, dal momento che sono entrambe sequenze di cose, ma le cose di cui sono sequenze sono piuttosto diverse.

Implementationally, str è memorizzato come UCS-? dove il ? è definita dall'implementazione, può essere UCS4, UCS2 o UCS1, a seconda delle opzioni di compilazione e dei codepoint presenti nella stringa rappresentata.


modifica "ma perché"?

Alcune cose che assomigliano al testo sono in realtà definite in altri termini. Un buon esempio di questo sono i numerosi protocolli Internet del mondo. Ad esempio, HTTP è un protocollo "testuale" che viene infatti definito utilizzando la sintassi ABNF comune in RFC. Questi protocolli sono espressi in termini di ottetti, non di caratteri, anche se può essere suggerita una codifica informale:

2.3. Valori terminali

Le regole si risolvono in una stringa di valori terminali, a volte chiamati
  personaggi. In ABNF, un carattere è semplicemente un numero intero non negativo.
  In determinati contesti, una mappatura specifica (codifica) di valori in a
  set di caratteri (come ASCII) sarà specificato.

Questa distinzione è importante, perché non è possibile inviare il testo su Internet, l'unica cosa che puoi fare è inviare byte. dire "testo ma nella codifica" foo "rende il formato molto più complesso, dal momento che clienti e server devono ora in qualche modo capire il business della codifica da soli, si spera nello stesso modo, poiché in definitiva devono passare i dati come byte Comunque. Questo è doppiamente inutile poiché questi protocolli sono raramente relativi alla gestione del testo, ed è solo una comodità per gli implementatori. Né i proprietari del server né gli utenti finali sono mai interessati a leggere le parole Transfer-Encoding: chunked, purché sia ​​il server che il browser lo capiscano correttamente.

In confronto, quando lavori con il testo, non ti interessa davvero come è codificato. Puoi esprimere "Heävy Mëtal Ümlaüts" nel modo che preferisci, ad eccezione di "Heδvy Mλtal άmlaόts"


i tipi distinti quindi ti danno un modo per dire "questo valore" significa "testo" o "byte".


20
2018-04-02 22:59



Come suggerisce il nome, un Python3 bytestring (o semplicemente a str in Python 2.7) è una stringa di byte. E, come altri hanno sottolineato, è immutabile.

È distinto da un Python3 str (o, più descrittivamente, a unicode in Python 2.7) che è a stringa di astratto caratteri unicode (a.k.a UTF-32, sebbene Python3 aggiunga una fantastica compressione sotto il cofano per ridurre l'effettivo ingombro di memoria simile a UTF-8, forse anche in un modo più generale).

Esistono essenzialmente tre modi per "interpretare" questi byte. Puoi guardare il valore numerico di un elemento, come questo:

>>> ord(b'Hello'[0])  # Python 2.7 str
72
>>> b'Hello'[0]  # Python 3 bytestring
72

Oppure puoi dire a Python di emettere uno o più elementi sul terminale (o un file, dispositivo, socket, ecc.) come caratteri a 8 bit, come questo:

>>> print b'Hello'[0] # Python 2.7 str
H
>>> import sys # Python 3 bytestring
>>> sys.stdout.write(str(b'Hello'[0:1], sys.stdout.encoding))
H

Come ha suggerito Jack, in quest'ultimo caso lo è il tuo terminale interpretariato il personaggio, non Python (anche se nel caso di Python3 tu fare avere convertire in str per essere compatibile con i terminali futuri che potrebbero non essere basato su byte. Questa è la fonte di molta confusione IMO).

Infine, come hai visto nella tua ricerca, puoi anche ottenere Pitone interpretare a bytestring. Ad esempio, puoi costruire un abstract unicode oggetto come questo in Python 2.7:

>>> u1234 = unicode(b'\xe1\x88\xb4', 'utf-8')
>>> u1234
u'\u1234'
>>> type(u1234)
<type 'unicode'>
>>> len(u1234)
1
>>> 

O così in Python 3:

>>> u1234 = str(b'\xe1\x88\xb4', 'utf-8')
>>> '\\u%04x' % ord(u1234)
\u1234
>>> type(u1234)
<class 'str'>
>>> len(u1234)
1

Ma l'astrazione Unicode non avviene automaticamente se non lo vuoi. Il punto di a bytestring è che puoi ottenere direttamente i byte. Anche nell'esempio precedente di Python2.7:

>>> len(b'\xe1\x88\xb4')
3
>>> b'\xe1\x88\xb4'[0]
'\xe1'

Puoi anche fare altre cose meravigliose con bytestrings, come sapere se si inseriranno in uno spazio riservato all'interno di un file, inviandoli direttamente su un socket, calcolando il HTTP content-length campo correttamente ed evitando Python Bug 8260. In breve, usa bytestrings quando i tuoi dati vengono elaborati e archiviati in byte.


3
2017-10-05 15:49



Gli oggetti byte sono sequenze immutabili di singoli byte. Il docs avere un'ottima spiegazione di cosa sono e come usarli.


0
2018-04-02 22:49