Estou usando o Python 3.6.1 e me deparei com algo muito estranho. Eu tinha um erro de digitação simples de atribuição de dicionário que levei muito tempo para encontrar.
context = {}
context["a"]: 2
print(context)
Resultado
{}
O que o código está context["a"]: 2
fazendo? Não levanta um SyntaxError
quando deveria IMO. A princípio pensei que fosse criar uma fatia. No entanto, a digitação repr(context["a"]: 2)
gera a SyntaxError
. Também digitei context["a"]: 2
no console e o console não imprimiu nada. Achei que talvez None
tivesse voltado , mas não tenho tanta certeza.
Também pensei que poderia ser uma instrução if de uma única linha, mas essa também não deve ser a sintaxe correta.
Além disso, context["a"]
deve levantar a KeyError
.
Estou perplexo. O que está acontecendo?
python
python-3.x
Justengel
fonte
fonte
Respostas:
Você escreveu acidentalmente uma anotação de variável sintaticamente correta . Esse recurso foi introduzido no Python 3.6 (consulte PEP 526 ).
Embora uma anotação de variável seja analisada como parte de uma atribuição anotada , a instrução de atribuição é opcional :
Assim, em
context["a"]: 2
context["a"]
é o alvo da anotação2
é a própria anotaçãocontext["a"]
é deixado não inicializadoO PEP afirma que "o alvo da anotação pode ser qualquer alvo de atribuição único válido, pelo menos sintaticamente (cabe ao verificador de tipo o que fazer com isso)" , o que significa que a chave não precisa existir para ser anotado (portanto, não
KeyError
). Aqui está um exemplo do PEP original:Normalmente, a expressão de anotação deve ser avaliada como um tipo Python - afinal, o uso principal das anotações é a sugestão de tipo, mas não é aplicada. A anotação pode ser qualquer expressão Python válida , independentemente do tipo ou valor do resultado.
Como você pode ver, neste momento as dicas de tipo são muito permissivas e raramente úteis, a menos que você tenha um verificador de tipo estático como mypy .
fonte
=
operador de atribuição, então? A chave não existe. Isso parece errado para mim.:
é o operador de atribuição. Estamos apenas "atribuindo" uma anotação de tipo sozinha, não uma chave. Duvido que haja alguma razão para permitir isso, apenas um efeito colateral não intencional de adicionar a sintaxe de anotação.x: str
e imediatamente seguida portype(x)
, o intérprete levantará aNameError
. IMO a sintaxe deve obrigar o objeto é pré-definido, ou é definido no local. Isso apenas introduz confusão.x = 'i am a string'
antesx: str
torna o último tipo de redundante. Isso não deveria ter sido adicionado. Foi bom como comentário; Eu nunca mostro isso usado de uma forma ou de outra.