A função Eval tenta executar e interpretar a string (argumento) passada a ela como código python. x = 1 print (eval ('x + 1')) A saída do código acima será 2. A desvantagem dessa abordagem é que, o usuário obtém independência da escrita do código, o que pode resultar em condições perigosas. acessando muitas variáveis e métodos passando parâmetro global e local na função eval.
ATIF IBAD KHAN
Respostas:
276
A função eval permite que um programa Python execute o código Python dentro de si.
haha, esse foi um exemplo trivial, mas você pode deixar o usuário digitar um comando arbitrário e fazer com que o python o execute. Assim, você pode fazer com que o usuário digite uma string de comando e, em seguida, faça com que o python a execute como código. Por exemplo, eval ("__ import __ ('os'). Remove ('file')").
BYS2
60
Vai parecer inútil até que você encontre uma necessidade. É usado em sites como o codepad.org para permitir a execução de scripts em um ambiente de teste. eval()também pode ser usado para executar código altamente dinâmico, mas você deve se conscientizar completamente dos riscos de segurança e desempenho antes de usá-lo.
George Cummins
6
@GeorgeCummins, codepad.org não usa eval, nem poderia fazer o que faz eval.
Mike Graham
16
@GeorgeCummins: codepag.org executa tudo em uma sandbox: uma cadeia chroot com ptrace faz check-in em uma máquina virtual para impedir que códigos maliciosos façam algo ruim. Muito mais complicado do que uma avaliação simples. Além disso, eval é específico do Python. O codepad suporta vários idiomas.
FogleBird 21/02/12
4
@GeorgeCummins, o codepad executa um sistema muito complexo para executar programas arbitrários com segurança. eval, além de inseguro, não pode executar programas inteiros como o codepad, porque só pode avaliar uma única expressão.
Mike Graham
165
eval()interpreta uma string como código. A razão pela qual tantas pessoas o alertaram sobre o uso disso é porque um usuário pode usá-lo como uma opção para executar código no computador. Se você tem eval(input())e osimportados, uma pessoa poderia digitar em input()os.system('rm -R *')que iria apagar todos os seus arquivos em seu diretório home. (Supondo que você tenha um sistema unix). Usar eval()é uma falha de segurança. Se você precisar converter seqüências de caracteres para outros formatos, tente usar coisas que fazem isso, como int().
Você quer dizer que usar evalwith input()é uma falha de segurança. Não insira input()uma declaração de avaliação e você ficará bem.
Rohmer 02/04
19
@Rohmer, dados inseguros podem vir de qualquer lugar: solicitações da Web, campos de entrada de formulário, leituras de arquivos, ... não apenas da entrada do console. Mesmo se você mesmo escrever os arquivos, ele ainda poderá conter entradas que vieram originalmente de uma fonte não confiável. O mesmo evalocorre com muitos problemas de segurança.
sanderd17
3
desde que inputgeralmente leva seus dados a partir do console o usuário poderia simplesmente sair do programa e digite rm -R *qualquer maneira ...
CZ
63
Muitas respostas boas aqui, mas nenhuma descreve o uso de eval()no contexto its globalse localskwargs, isto é eval(expression, globals=None, locals=None)(consulte a documentação evalaqui ).
Eles podem ser usados para limitar as funções disponíveis através da evalfunção. Por exemplo, se você carregar um intérprete python novo, o locals()e globals()será o mesmo e terá algo parecido com isto:
Certamente, existem funções no builtinsmódulo que podem causar danos significativos a um sistema. Mas é possível bloquear tudo e qualquer coisa que não queremos disponível. Vamos dar um exemplo. Digamos que queremos construir uma lista para representar um domínio dos núcleos disponíveis em um sistema. Para mim eu tenho 8 núcleos, então eu gostaria de uma lista [1, 8].
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')[1,8]
Da mesma forma, tudo __builtins__está disponível.
>>>eval('abs(-1)')1
Está bem. Então, vemos uma função que queremos expor e um exemplo de um método (de muitos que pode ser muito mais complexo) que não queremos que seja exposto. Então, vamos bloquear tudo.
Bloqueamos efetivamente todas as __builtins__funções e, como tal, trouxemos um nível de proteção ao nosso sistema. Nesse ponto, podemos começar a adicionar novamente funções que queremos que sejam expostas.
Agora temos a cpu_countfunção disponível enquanto ainda bloqueamos tudo o que não queremos. Na minha opinião, isso é super poderoso e claramente do escopo das outras respostas, não de uma implementação comum. Existem inúmeros usos para algo assim e, desde que seja manuseado corretamente, eu pessoalmente acho que evalpode ser usado com segurança por um grande valor.
NB
Outra coisa interessante sobre isso kwargsé que você pode começar a usar uma abreviação para seu código. Digamos que você use eval como parte de um pipeline para executar algum texto importado. O texto não precisa ter o código exato, ele pode seguir algum formato de arquivo de modelo e ainda executar o que você desejar. Por exemplo:
>>>from os import cpu_count
>>>eval('[1,cores]',{'__builtins__':None},{'cores': cpu_count()})[1,8]
No Python 2.x input(...)é equivalente eval(raw_input(...)), no Python 3.x raw_inputfoi renomeado input, o que eu suspeito levar à sua confusão (você provavelmente estava procurando a documentação inputdo Python 2.x). Além disso, eval(input(...))funcionaria bem no Python 3.x, mas aumentaria um TypeErrorno Python 2.
Nesse caso, evalé usado para coagir a sequência retornada inputem uma expressão e interpretada. Geralmente, isso é considerado uma má prática.
Por que devo digitá-lo entre aspas? A entrada está recebendo uma string e a passa para avaliação, não executando o código, então eu ficaria bem se simplesmente digitasse 1 + 1 ... ¿?
JC Rocamonde
O problema é que você está misturando P2.xe 3.x. No Python 2, seu código funciona, mas não faz sentido avaliar duas vezes. No python 3, ele não retorna e retorna uma string.
JC Rocamonde
6
eval()avalia a cadeia passada como uma expressão Python e retorna o resultado. Por exemplo, eval("1 + 1")interpreta e executa a expressão "1 + 1"e retorna o resultado (2).
Uma razão pela qual você pode estar confuso é porque o código que você citou envolve um nível de indireção. A chamada de função interna (entrada) é executada primeiro para que o usuário veja o prompt "blah". Vamos imaginar que eles respondem com "1 + 1" (aspas adicionadas para maior clareza, não as digitam ao executar o programa), a função de entrada retorna essa string, que é então passada para a função externa (eval) que interpreta a string e retorna o resultado (2).
eval(), como o nome sugere, avalia o argumento passado.
raw_input()está agora input()nas versões python 3.x. Portanto, o exemplo mais comumente encontrado para o uso de eval()é seu uso para fornecer a funcionalidade input()fornecida na versão 2.x do python. raw_input retornou os dados inseridos pelo usuário como uma sequência, enquanto a entrada avaliou o valor dos dados inseridos e os retornou.
eval(input("bla bla"))assim, replica a funcionalidade do input()2.x, isto é, da avaliação dos dados inseridos pelo usuário.
Em resumo: eval()avalia os argumentos passados para ele e, portanto, eval('1 + 1')retornou 2.
Uma das aplicações úteis de eval()é avaliar expressões python da string. Por exemplo, carregar da representação de sequência de arquivos do dicionário:
Outra opção se você deseja limitar a cadeia de avaliação a literais simples é usar ast.literal_eval(). Alguns exemplos:
import ast
# print(ast.literal_eval('')) # SyntaxError: unexpected EOF while parsing# print(ast.literal_eval('a')) # ValueError: malformed node or string# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax# print(ast.literal_eval('1+1')) # 2: but only works due to a quirk in parser# print(ast.literal_eval('1*1')) # ValueError: malformed node or stringprint(ast.literal_eval("{'a':1}"))# {'a':1}
Avalie com segurança um nó de expressão ou uma sequência que contém um literal Python ou exibição de contêiner. A cadeia ou nó fornecido pode apenas consistir nas seguintes estruturas literais do Python: cadeias, bytes, números, tuplas, listas, dictos, conjuntos, booleanos e Nenhum.
Isso pode ser usado para avaliar com segurança seqüências de caracteres contendo valores Python de fontes não confiáveis, sem a necessidade de analisar os próprios valores. É não capaz de avaliar expressões complexas arbitrariamente, por exemplo envolvendo operadores ou indexação.
Permitir expressões de operador com literais é possível, mas muito mais complexo que a implementação atual. Uma implementação simples não é segura: você pode induzir basicamente o uso ilimitado da CPU e da memória sem esforço (tente "9 ** 9 ** 9" ou "[None] * 9 ** 9").
Quanto à utilidade, esta função é útil para "ler de volta" valores literais e contêineres, conforme especificado por repr (). Por exemplo, isso pode ser usado para serialização em um formato semelhante, mas mais poderoso que o JSON.
ast.literal_evalnão suporta operadores, ao contrário do seu '1+1'exemplo. No entanto, ele suporta listas, números, seqüências de caracteres etc, e, portanto, é uma boa alternativa para evalcasos de uso comuns .
Respostas:
A função eval permite que um programa Python execute o código Python dentro de si.
exemplo eval (shell interativo):
fonte
eval()
também pode ser usado para executar código altamente dinâmico, mas você deve se conscientizar completamente dos riscos de segurança e desempenho antes de usá-lo.eval
, nem poderia fazer o que fazeval
.eval
, além de inseguro, não pode executar programas inteiros como o codepad, porque só pode avaliar uma única expressão.eval()
interpreta uma string como código. A razão pela qual tantas pessoas o alertaram sobre o uso disso é porque um usuário pode usá-lo como uma opção para executar código no computador. Se você temeval(input())
eos
importados, uma pessoa poderia digitar eminput()
os.system('rm -R *')
que iria apagar todos os seus arquivos em seu diretório home. (Supondo que você tenha um sistema unix). Usareval()
é uma falha de segurança. Se você precisar converter seqüências de caracteres para outros formatos, tente usar coisas que fazem isso, comoint()
.fonte
eval
withinput()
é uma falha de segurança. Não insirainput()
uma declaração de avaliação e você ficará bem.eval
ocorre com muitos problemas de segurança.input
geralmente leva seus dados a partir do console o usuário poderia simplesmente sair do programa e digiterm -R *
qualquer maneira ...Muitas respostas boas aqui, mas nenhuma descreve o uso de
eval()
no contexto itsglobals
elocals
kwargs, isto éeval(expression, globals=None, locals=None)
(consulte a documentaçãoeval
aqui ).Eles podem ser usados para limitar as funções disponíveis através da
eval
função. Por exemplo, se você carregar um intérprete python novo, olocals()
eglobals()
será o mesmo e terá algo parecido com isto:Certamente, existem funções no
builtins
módulo que podem causar danos significativos a um sistema. Mas é possível bloquear tudo e qualquer coisa que não queremos disponível. Vamos dar um exemplo. Digamos que queremos construir uma lista para representar um domínio dos núcleos disponíveis em um sistema. Para mim eu tenho 8 núcleos, então eu gostaria de uma lista[1, 8]
.Da mesma forma, tudo
__builtins__
está disponível.Está bem. Então, vemos uma função que queremos expor e um exemplo de um método (de muitos que pode ser muito mais complexo) que não queremos que seja exposto. Então, vamos bloquear tudo.
Bloqueamos efetivamente todas as
__builtins__
funções e, como tal, trouxemos um nível de proteção ao nosso sistema. Nesse ponto, podemos começar a adicionar novamente funções que queremos que sejam expostas.Agora temos a
cpu_count
função disponível enquanto ainda bloqueamos tudo o que não queremos. Na minha opinião, isso é super poderoso e claramente do escopo das outras respostas, não de uma implementação comum. Existem inúmeros usos para algo assim e, desde que seja manuseado corretamente, eu pessoalmente acho queeval
pode ser usado com segurança por um grande valor.NB
Outra coisa interessante sobre isso
kwargs
é que você pode começar a usar uma abreviação para seu código. Digamos que você use eval como parte de um pipeline para executar algum texto importado. O texto não precisa ter o código exato, ele pode seguir algum formato de arquivo de modelo e ainda executar o que você desejar. Por exemplo:fonte
No Python 2.x
input(...)
é equivalenteeval(raw_input(...))
, no Python 3.xraw_input
foi renomeadoinput
, o que eu suspeito levar à sua confusão (você provavelmente estava procurando a documentaçãoinput
do Python 2.x). Além disso,eval(input(...))
funcionaria bem no Python 3.x, mas aumentaria umTypeError
no Python 2.Nesse caso,
eval
é usado para coagir a sequência retornadainput
em uma expressão e interpretada. Geralmente, isso é considerado uma má prática.fonte
input
significa o queraw_input
fez no 2.x.Talvez um exemplo enganoso de ler e interpretar uma linha.
Experimente
eval(input())
e digite"1+1"
- isso deve ser impresso2
. Eval avalia expressões.fonte
eval()
avalia a cadeia passada como uma expressão Python e retorna o resultado. Por exemplo,eval("1 + 1")
interpreta e executa a expressão"1 + 1"
e retorna o resultado (2).Uma razão pela qual você pode estar confuso é porque o código que você citou envolve um nível de indireção. A chamada de função interna (entrada) é executada primeiro para que o usuário veja o prompt "blah". Vamos imaginar que eles respondem com "1 + 1" (aspas adicionadas para maior clareza, não as digitam ao executar o programa), a função de entrada retorna essa string, que é então passada para a função externa (eval) que interpreta a string e retorna o resultado (2).
Leia mais sobre eval aqui .
fonte
eval()
, como o nome sugere, avalia o argumento passado.raw_input()
está agorainput()
nas versões python 3.x. Portanto, o exemplo mais comumente encontrado para o uso deeval()
é seu uso para fornecer a funcionalidadeinput()
fornecida na versão 2.x do python. raw_input retornou os dados inseridos pelo usuário como uma sequência, enquanto a entrada avaliou o valor dos dados inseridos e os retornou.eval(input("bla bla"))
assim, replica a funcionalidade doinput()
2.x, isto é, da avaliação dos dados inseridos pelo usuário.Em resumo:
eval()
avalia os argumentos passados para ele e, portanto,eval('1 + 1')
retornou 2.fonte
Uma das aplicações úteis de
eval()
é avaliar expressões python da string. Por exemplo, carregar da representação de sequência de arquivos do dicionário:Leia-o como uma variável e edite-o:
Resultado:
fonte
eval
faz?Estou atrasado para responder a essa pergunta, mas ninguém parece dar uma resposta clara à pergunta.
Se um usuário digitar um valor numérico,
input()
retornará uma sequência.Portanto,
eval()
avaliaremos o valor retornado (ou expressão) que é uma string e retornará um número inteiro / float.É claro que essa é uma prática ruim.
int()
oufloat()
deve ser usado em vez deeval()
neste caso.fonte
Outra opção se você deseja limitar a cadeia de avaliação a literais simples é usar
ast.literal_eval()
. Alguns exemplos:Dos documentos :
Por que é tão limitado, na lista de discussão :
fonte
ast.literal_eval
não suporta operadores, ao contrário do seu'1+1'
exemplo. No entanto, ele suporta listas, números, seqüências de caracteres etc, e, portanto, é uma boa alternativa paraeval
casos de uso comuns .