Você poderia me dizer por que '?\\\?'=='?\\\\?'dá True? Isso me deixa louco e não consigo encontrar uma resposta razoável ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
Você poderia me dizer por que '?\\\?'=='?\\\\?'dá True? Isso me deixa louco e não consigo encontrar uma resposta razoável ...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
list()mesmo:>>> '?\\\?' '?\\\\?'
Respostas:
Basicamente, porque o python é ligeiramente tolerante no processamento de barra invertida. Citando https://docs.python.org/2.0/ref/strings.html :
Ao contrário do C padrão, todas as sequências de escape não reconhecidas são deixadas na string inalteradas, ou seja, a barra invertida é deixada na string .
(Ênfase no original)
Portanto, em python, não é que três barras invertidas são iguais a quatro, é que quando você segue a barra invertida com um caractere como ?, os dois juntos surgem como dois caracteres, porque \?não é uma sequência de escape reconhecida.
'escape''d'). Você nem mesmo precisa se lembrar de outros personagens lá!
Isso ocorre porque a barra invertida atua como um caractere de escape para o (s) caractere (s) imediatamente seguinte (s), se a combinação representar uma sequência de escape válida. A dúzia ou mais de sequências de escape estão listadas aqui . Eles incluem os óbvios, como nova linha \n, tabulação horizontal \t, retorno de carro \re outros mais obscuros, como caracteres Unicode nomeados usando \N{...}, por exemplo, \N{WAVY DASH}que representa caractere Unicode \u3030. O ponto principal é que, se a sequência de escape não for conhecida, a sequência de caracteres será deixada na string como está.
Parte do problema também pode ser que a saída do interpretador Python está enganando você. Isso ocorre porque as barras invertidas têm escape quando exibidas. No entanto, se você imprimir essas strings, verá as barras invertidas extras desaparecerem.
>>> '?\\\?'
'?\\\\?'
>>> 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
Para seus exemplos específicos, no primeiro caso '?\\\?', o primeiro \escapa da segunda barra invertida deixando uma única barra invertida, mas a terceira barra invertida permanece como uma barra invertida porque \?não é uma sequência de escape válida. Portanto, a string resultante é ?\\?.
Para o segundo caso '?\\\\?', a primeira barra invertida escapa da segunda e a terceira barra invertida escapa da quarta, que resulta na string ?\\?.
É por isso que três barras invertidas são iguais a quatro:
>>> '?\\\?' == '?\\\\?'
True
Se você deseja criar uma string com 3 barras invertidas, pode escapar de cada barra invertida:
>>> '?\\\\\\?'
'?\\\\\\?'
>>> print('?\\\\\\?')
?\\\?
ou você pode achar strings "brutas" mais compreensíveis:
>>> r'?\\\?'
'?\\\\\\?'
>>> print(r'?\\\?')
?\\\?
Isso muda o processamento da sequência de escape para o literal de string. Consulte Literais de string para obter mais detalhes.
'?\\\?'=='?\\?'dá False, eu digitei errado. Isso deve ser '?\\\?'=='?\\\\?'como a pergunta indica, eu corrigi.
Na página de análise lexical python em literais de string em: https://docs.python.org/2/reference/lexical_analysis.html
Existe uma tabela que lista todas as sequências de escape reconhecidas.
\\ é uma sequência de escape que é === \
\? não é uma sequência de escape e é === \?
então '\\\\' é '\\' seguido por '\\' que é '\\' (dois com escape \)
e '\\\' é '\\' seguido por '\' que também é '\\' (um com escape \ e um bruto \)
Além disso, deve-se observar que o python não distingue entre aspas simples e duplas em torno de um literal de string, ao contrário de algumas outras linguagens.
Portanto, 'String' e "String" são exatamente a mesma coisa em python, eles não afetam a interpretação das sequências de escape.
A resposta de mhawke praticamente cobre isso, eu só quero reformulá-la de uma forma mais concisa e com exemplos mínimos que ilustram esse comportamento.
Acho que uma coisa a acrescentar é que o processamento de escape se move da esquerda para a direita, de modo que \nprimeiro encontra a barra invertida e, em seguida, procura um caractere para escapar, em seguida, encontra ne escapa; \\nencontra a primeira barra invertida, encontra a segunda e escapa dela, então a encontra ne a vê como um n literal; \?encontra a barra invertida e procura um caractere para escapar, encontra o ?que não pode ser escapado, e então trata\ como uma barra invertida literal.
Como mhawke observou, a chave aqui é que o interpretador interativo escapa da barra invertida ao exibir uma string. Suponho que a razão para isso é garantir que as strings de texto copiadas do interpretador para o editor de código sejam strings de python válidas. No entanto, neste caso, essa permissão para conveniência causa confusão.
>>> 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
\\?