Potresti dirmi perché '?\\\?'=='?\\\\?'dà True? Questo mi fa impazzire e non riesco a trovare una risposta ragionevole ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
Potresti dirmi perché '?\\\?'=='?\\\\?'dà True? Questo mi fa impazzire e non riesco a trovare una risposta ragionevole ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
list()nemmeno:>>> '?\\\?' '?\\\\?'
Risposte:
Fondamentalmente, perché Python è leggermente indulgente nell'elaborazione del backslash. Citando da https://docs.python.org/2.0/ref/strings.html :
A differenza dello standard C, tutte le sequenze di escape non riconosciute vengono lasciate invariate nella stringa, ovvero la barra rovesciata viene lasciata nella stringa .
(Enfasi nell'originale)
Pertanto, in Python, non è che tre barre rovesciate siano uguali a quattro, è che quando si segue una barra rovesciata con un carattere simile ?, le due insieme vengono visualizzate come due caratteri, perché \?non è una sequenza di escape riconosciuta.
'escape''d'). Non devi nemmeno ricordare altri personaggi lì!
Questo perché la barra rovesciata funge da carattere di escape per i caratteri immediatamente successivi, se la combinazione rappresenta una sequenza di escape valida. Le dozzine di sequenze di escape sono elencate qui . Includono quelli ovvi come la nuova riga \n, la tabulazione orizzontale \t, il ritorno a capo \re quelli più oscuri come i caratteri Unicode denominati utilizzando \N{...}, ad esempio, \N{WAVY DASH}che rappresenta il carattere Unicode \u3030. Il punto chiave però è che se la sequenza di escape non è nota, la sequenza di caratteri viene lasciata nella stringa così com'è.
Parte del problema potrebbe anche essere che l'output dell'interprete Python ti sta fuorviando. Questo perché i backslash vengono sottoposti a escape quando vengono visualizzati. Tuttavia, se stampi quelle stringhe, vedrai scomparire le barre rovesciate extra.
>>> '?\\\?'
'?\\\\?'
>>> print('?\\\?')
?\\?
>>> '?\\\?' == '?\\?' # I don't know why you think this is True???
False
>>> '?\\\?' == r'?\\?' # but if you use a raw string for '?\\?'
True
>>> '?\\\\?' == '?\\\?' # this is the same string... see below
True
Per i tuoi esempi specifici, nel primo caso '?\\\?', il primo \sfugge al secondo backslash lasciando un singolo backslash, ma il terzo backslash rimane come backslash perché \?non è una sequenza di escape valida. Quindi la stringa risultante è ?\\?.
Per il secondo caso '?\\\\?', il primo backslash sfugge al secondo e il terzo backslash sfugge al quarto che risulta nella stringa ?\\?.
Ecco perché tre backslash sono uguali a quattro:
>>> '?\\\?' == '?\\\\?'
True
Se desideri creare una stringa con 3 barre rovesciate, puoi eseguire l'escape di ciascuna barra rovesciata:
>>> '?\\\\\\?'
'?\\\\\\?'
>>> print('?\\\\\\?')
?\\\?
oppure potresti trovare stringhe "grezze" più comprensibili:
>>> r'?\\\?'
'?\\\\\\?'
>>> print(r'?\\\?')
?\\\?
Questo trasforma l'elaborazione della sequenza di escape per la stringa letterale. Vedere String Literals per ulteriori dettagli.
'?\\\?'=='?\\?'dà False, l'ho digitato male. Dovrebbe essere '?\\\?'=='?\\\\?'come indica la domanda, l'ho corretto.
Dalla pagina di analisi lessicale di Python sotto stringhe letterali su: https://docs.python.org/2/reference/lexical_analysis.html
C'è una tabella che elenca tutte le sequenze di escape riconosciute.
\\ è una sequenza di escape che è === \
\? non è una sequenza di escape ed è === \?
quindi "\\\\" è "\\" seguito da "\\" che è "\\" (due \\ con escape)
e "\\\" è "\\" seguito da "\" che è anche "\\" (uno con escape \ e uno grezzo \)
Inoltre, va notato che python non distingue tra virgolette singole e doppie che circondano una stringa letterale, a differenza di altri linguaggi.
Quindi "String" e "String" sono la stessa cosa in Python, non influenzano l'interpretazione delle sequenze di escape.
La risposta di mhawke praticamente lo copre, voglio solo riformularlo in una forma più concisa e con esempi minimi che illustrano questo comportamento.
Immagino che una cosa da aggiungere sia che l'elaborazione dell'escape si sposta da sinistra a destra, in modo che \nprima trova il backslash e poi cerca un carattere da scappare, poi lo trova ne lo sfugge; \\ntrova la prima barra rovesciata, trova la seconda ed esegue l'escape, quindi la trova ne la vede come una n letterale; \?trova la barra rovesciata e cerca un carattere di cui eseguire l'escape, trova a ?cui non è possibile eseguire l'escape e quindi tratta \come una barra rovesciata letterale.
Come notato da mhawke, la chiave qui è che l'interprete interattivo sfugge alla barra rovesciata quando mostra una stringa. Immagino che il motivo sia quello di garantire che le stringhe di testo copiate dall'interprete nell'editor di codice siano stringhe Python valide. Tuttavia, in questo caso, questa indennità per comodità crea confusione.
>>> print('\?') # \? is not a valid escape code so backslash is left as-is
\?
>>> print('\\?') # \\ is a valid escape code, resulting in a single backslash
'\?'
>>> '\?' # same as first example except that interactive interpreter escapes the backslash
\\?
>>> '\\?' # same as second example, backslash is again escaped
\\?